Gorgon Game Engine
Embedding.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <tuple>
4 #include <type_traits>
5 #include <cmath>
6 
7 #include "Reflection.h"
8 #include "VirtualMachine.h"
9 #include "Exceptions.h"
10 #include "../Scripting.h"
11 #include "../Utils/Assert.h"
12 #include "../TMP.h"
13 
20 namespace Gorgon {
21 namespace Scripting {
22 
23  template<class T_>
24  using StringFromFn = std::string(*)(const T_ &);
25 
26  template<class T_>
27  using ParseFn = T_(*)(const std::string &);
28 
29  template<class T_>
30  std::string ToEmptyString(const T_ &) {
31  return "";
32  }
33 
34  template<class T_>
35  T_ ParseThrow(const std::string &) { throw std::runtime_error("This type cannot be parsed."); }
36 
37  template <
38  class T_,
39  StringFromFn<T_> ToString_=String::From<T_>,
40  ParseFn<T_> Parse_=String::To<T_>
41  >
42  class MappedValueType;
43 
44  template <
45  class T_,
46  StringFromFn<T_> ToString_=&String::From<T_>,
47  ParseFn<T_*> Parse_=&ParseThrow<T_*>
48  >
49  class MappedReferenceType;
50 
51 
53  template<class F_>
56  using traits = TMP::FunctionTraits<F_>;
57  template<int P_>
58  using param = typename traits::template Arguments<P_>::Type;
59  public:
60 
62  template<class ...P_>
64  variant(returntype, std::move(parameters), tags...), fn(fn)
65  { }
66 
67  virtual Data Call(bool ismethod, const std::vector<Data> &parameters) const override {
68  auto ret=callfn<typename traits::ReturnType>(typename TMP::Generate<traits::Arity>::Type(), parameters);
69 
70  if(ismethod) {
71  if(ret.IsValid()) {
72  VirtualMachine::Get().GetOutput()<<ret<<std::endl<<std::endl;
73 
74  return Data::Invalid();
75  }
76  }
77 
78  return ret;
79  }
80 
81  private:
82 
83  template<class T_>
84  struct extractvector {
85  enum { isvector = false };
86 
87  using inner = T_;
88  };
89 
90  template<template<class, class> class V_, class T_, class A_>
91  struct extractvector<V_<T_, A_>> {
92  enum { isvector = std::is_same<V_<T_, A_>, std::vector<T_, A_>>::value };
93 
94  using inner = T_;
95  };
96 
97  template<template<class, class> class V_, class T_, class A_>
98  struct extractvector<const V_<T_, A_>&> {
99  enum { isvector = std::is_same<V_<T_, A_>, std::vector<T_, A_>>::value };
100 
101  using inner = T_;
102  };
103 
104  //checks if this type is a reference that cannot be initialized from a value
105  template<class T_>
106  struct is_nontmpref {
107  enum {
108  value =
109  !std::is_copy_constructible<typename std::remove_const<typename std::remove_reference<T_>::type>::type>::value ||
110  (std::is_reference<T_>::value && !std::is_const<typename std::remove_reference<T_>::type>::value) };
111  };
112 
113  //checks if this type is a reference that cannot be initialized from a value
114  template<class T_>
115  struct is_nonconstref {
116  enum {
117  value = (std::is_reference<T_>::value && !std::is_const<typename std::remove_reference<T_>::type>::value)
118  };
119  };
120 
121  template<class T_>
122  inline typename std::enable_if<
123  is_nontmpref<T_>::value && std::is_const<typename std::remove_reference<T_>::type>::value,
124  T_
125  >::type castto(const Data &d) const {
126  using regtype=typename std::remove_reference<T_>::type;
127  if(d.IsConstant()) {
128  return d.ReferenceValue<T_>();
129  }
130  else {
131  return d.ReferenceValue<typename std::remove_const<regtype>::type &>();
132  }
133  }
134 
135  template<class T_>
136  inline typename std::enable_if<
137  is_nontmpref<T_>::value && !std::is_const<typename std::remove_reference<T_>::type>::value,
138  T_
139  >::type castto(const Data &d) const {
140  using regtype=typename std::remove_reference<T_>::type;
141 
142  ASSERT(!d.IsConstant(), "Constant data is being submitted to non-const reference");
143  return d.ReferenceValue<T_>();
144  }
145 
146  template<class T_>
147  inline typename std::enable_if<!is_nontmpref<T_>::value && std::is_pointer<T_>::value, T_>::type castto(const Data &d) const {
148  bool isconst=std::is_const<typename std::remove_pointer<T_>::type>::value;
149 
150  if(isconst && !d.IsConstant()) {
151  return d.GetValue<typename std::remove_const<typename std::remove_pointer<T_>::type>::type *>();
152  }
153  else {
154  return d.GetValue<T_>();
155  }
156  }
157 
158  template<class T_>
159  inline typename std::enable_if<!is_nontmpref<T_>::value && !std::is_pointer<T_>::value, T_>::type castto(const Data &d) const {
160  bool isref=false, isconst=false;
161  if(std::is_reference<T_>::value) {
162  isref=true;
163  isconst=std::is_const<typename std::remove_reference<T_>::type>::value;
164  }
165  else {
166  isconst=std::is_const<T_>::value;
167  }
168 
169  if(isconst && !d.IsConstant()) {
170  if(isref) {
171  return d.GetValue<typename std::remove_const<typename std::remove_reference<T_>::type>::type &>();
172  }
173  else {
174  return d.GetValue<typename std::remove_const<T_>::type>();
175  }
176  }
177  else {
178  return d.GetValue<T_>();
179  }
180  }
181 
182  template<int P_>
183  typename std::enable_if<!extractvector<param<P_>>::isvector, param<P_>>::type
184  accumulatevector(const std::vector<Data> &parameters) const {
185  Utils::ASSERT_FALSE("Invalid accumulation");
186  }
187 
188  template<int P_>
189  typename std::enable_if<extractvector<param<P_>>::isvector,
190  typename std::remove_const<typename std::remove_reference<param<P_>>::type>::type>::type
191  accumulatevector(const std::vector<Data> &parameters) const {
192  typename std::remove_const<typename std::remove_reference<param<P_>>::type>::type v;
193  for(unsigned i=P_; i<parameters.size(); i++) {
194  v.push_back(castto<typename extractvector<param<P_>>::inner>(parameters[i]));
195  }
196 
197  return v;
198  }
199 
200  template<int P_>
201  inline typename TMP::Choose<
202  is_nontmpref<param<P_>>::value && !extractvector<param<P_>>::isvector,
203  std::reference_wrapper<typename std::remove_reference<param<P_>>::type>,
204  typename TMP::Choose<extractvector<param<P_>>::isvector,
205  typename std::remove_const<typename std::remove_reference<param<P_>>::type>::type,
206  param<P_>
207  >::Type
208  >::Type cast(const std::vector<Data> &parameters) const {
209  bool b=is_nontmpref<param<P_>>::value;
210  if(P_-(parent->IsMember() && !parent->IsStatic())==this->parameters.size()-1 && repeatlast) {
211  ASSERT(extractvector<param<P_>>::isvector, "Repeating parameter should be a vector");
212 
213  return accumulatevector<P_>(parameters);
214  }
215 
216  ASSERT(parameters.size()>P_, "Number of parameters does not match");
217 
218  return castto<param<P_>>(parameters[P_]);
219  }
220 
221  template<class R_, int ...S_>
222  typename std::enable_if<!std::is_same<R_, void>::value && !std::is_reference<R_>::value && !std::is_pointer<R_>::value, Data>::type
223  callfn(TMP::Sequence<S_...>, const std::vector<Data> &parameters) const {
224  Data data;
225 
226  ASSERT((!returnsref || returntype==Types::Variant()), "Embedded function does not return a reference");
227 
228  data=Data(returntype, Any(
229  std::bind(fn, cast<S_>(parameters)...)()
230  ), false, returnsconst);
231 
232  ASSERT((!returnsref || (returntype==Types::Variant() && data.GetValue<Data>().IsReference())),
233  "Embedded function does not return a reference");
234 
235  if(returnsref && returntype==Types::Variant()) {
236  if(!data.GetValue<Data>().IsReference()) {
237  throw CastException("Non-reference variant", "Reference variant", "While returning value from "+parent->GetName());
238  }
239  }
240 
241  return data;
242  }
243 
244  template<class R_, int ...S_>
245  typename std::enable_if<!std::is_same<R_, void>::value && std::is_reference<R_>::value && !std::is_pointer<R_>::value, Data>::type
246  callfn(TMP::Sequence<S_...>, const std::vector<Data> &parameters) const {
247  Data data;
249  data=Data(returntype, Any(
250  &std::bind(fn, cast<S_>(parameters)...)()
251  ), true, returnsconst);
252  }
253  else {
254  Utils::ASSERT_FALSE("Cannot happen");
255  }
256 
257  return data;
258  }
259 
260  template<class R_, int ...S_>
261  typename std::enable_if<!std::is_same<R_, void>::value && std::is_pointer<R_>::value, Data>::type
262  callfn(TMP::Sequence<S_...>, const std::vector<Data> &parameters) const {
263  Data data;
265  data=Data(returntype, Any(
266  std::bind(fn, cast<S_>(parameters)...)()
267  ), true, returnsconst);
268  }
269  else {
270  Utils::ASSERT_FALSE("Cannot happen");
271  }
272 
273  return data;
274  }
275 
276  template<class R_, int ...S_>
277  typename std::enable_if<std::is_same<R_, void>::value, Data>::type
278  callfn(TMP::Sequence<S_...>, const std::vector<Data> &parameters) const {
279  std::bind(fn, cast<S_>(parameters)...)();
280 
281  return Data::Invalid();
282  }
283 
284  template<int P_>
285  void checkparam() {
286  using T=param<P_>;
287  TMP::AbstractRTTC<typename std::remove_pointer<T>::type> rtt;
288 
289  bool ismember=parent->IsMember() && !parent->IsStatic();
290 
291  //** Constant and reference checks
292  //nonconst ptr or reference
293  if(is_nonconstref<T>::value || (std::is_pointer<T>::value && !std::is_const<typename std::remove_pointer<T>::type>::value)) {
294  //this pointer
295  if(P_==0 && ismember) {
296  //should not be a constant
297  ASSERT(
298  !IsConstant(),
299  "This function variant is marked as const, yet its implementation requires non-const "
300  "pointer or reference\n"
301  "in function "+parent->GetName(), 4, 3
302  );
303  }
304  else {
305  const auto &param=parameters[P_-ismember];
306 
307  //repeating parameters cannot be a non-const reference or a pointer
308  ASSERT(
309  P_-ismember!=parameters.size()-1 || !repeatlast,
310  "Repeating parameter vectors cannot be non-const references"
311  "in function "+parent->GetName(), 4, 3
312  );
313 
314  //parameter should be a reference
315  ASSERT(param.IsReference(),
316  "Parameter #"+String::From(P_-ismember)+" is not declared as reference, "
317  "yet its implementation is\n"
318  "in function "+parent->GetName(), 4, 3
319  );
320 
321  //and should not be a constant
322  ASSERT(!param.IsConstant(),
323  "Parameter #"+String::From(P_-ismember)+" is declared as constant, "
324  "yet its implementation is not const\n"
325  "in function "+parent->GetName(), 4, 3
326  );
327 
328  if(is_nonconstref<T>::value) {
329  ASSERT(!param.AllowsNull(),
330  "Parameter #"+String::From(P_-ismember)+" is a reference "
331  "and its implementation allows nullptr. This may cause crashes\n"
332  "in function "+parent->GetName(), 4, 3
333  );
334  }
335  }
336  }
337  //const pointer
338  else if(std::is_pointer<T>::value) {
339  //this pointer
340  if(P_==0 && ismember) {
341 #ifdef TEST
342  //it is ok if the function is not marked as constant, but this might be a mistake
343  if(!IsConstant()) {
344  std::cout<<"This function variant is not marked as const, yet its implementation requires const "
345  "pointer\n"
346  "in function "+parent->GetName()<<std::endl;
347  }
348 #endif
349  }
350  else {
351  const auto &param=parameters[P_-ismember];
352 
353  //a repeating parameter cannot be a pointer
354  ASSERT(
355  P_-ismember!=parameters.size()-1 || !repeatlast,
356  "Repeating parameter vectors cannot be a pointer"
357  );
358 
359  //parameter should be a reference, since type is a pointer
360  ASSERT(param.IsReference(),
361  "Parameter #"+(String::From(P_-ismember+1)+", "+param.GetName())+" is not declared as reference, "
362  "yet its implementation is\n"
363  "in function "+parent->GetName(), 4, 3
364  );
365 
366 #ifdef TEST
367  //it is ok if the parameter is not marked as constant, but this might be a mistake
368  if(!param.IsConstant()) {
369  std::cout<< "Parameter #"+(String::From(P_-ismember+1)+", "+param.GetName())+" is not marked as const, "
370  "yet its implementation requires const pointer\n"
371  "in function "+parent->GetName()<<std::endl;
372  }
373 #endif
374  }
375  }
376  else if(std::is_reference<T>::value) { //const ref can be anything
377  if(!ismember || P_!=0) {
378  const auto &param=parameters[P_-ismember];
379 
380  //if really is a reference
381  if(param.IsReference()) {
382  //it cannot accept null
383  ASSERT(!param.AllowsNull(),
384  "Parameter #"+String::From(P_-ismember)+" is a reference "
385  "and its implementation allows nullptr. This may cause crashes\n"
386  "in function "+parent->GetName(), 4, 3
387  );
388  }
389  }
390  }
391  else if(std::is_const<T>::value) { //constant value type
392  //this pointer
393  if(P_==0 && ismember) {
394  //should not a be constant, this behavior can be supported but it might lead to more problems
395  ASSERT(
396  IsConstant(),
397  "This function variant is marked as a non-const member function, "
398  "yet its implementation requests a constant value which cannot modify the this pointer.\n"
399  "in function "+parent->GetName(), 4, 3
400  );
401  }
402  else {
403  const auto &param=parameters[P_-ismember];
404 
405  //if not the repeating parmeter
406  if(P_-ismember!=parameters.size()-1 || !repeatlast) {
407  ASSERT(!param.IsReference(),
408  "Parameter #"+(String::From(P_-ismember+1)+", "+param.GetName())+" is declared as reference "
409  "yet its implementation not\n"
410  "in function "+parent->GetName(), 4, 3
411  );
412 
413 #ifdef TEST
414  //it is ok if the parameter is not marked as constant, but this might be a mistake
415  if(!param.IsConstant()) {
416  std::cout<<"Parameter #"+(String::From(P_-ismember+1)+", "+param.GetName())+" is not marked as const, yet its implementation requires const "
417  "value\n"
418  "in function "+parent->GetName()<<std::endl;
419  }
420 #endif
421  }
422  //else const std::vector<...> is allowed
423  }
424  }
425  else { //normal value type
426  //this pointer
427  if(P_==0 && ismember) {
428  //if passed by value, this function cannot modify this pointer, and therefore, should be constant
429  ASSERT(
430  IsConstant(),
431  "This function variant is marked as a non-const member function, "
432  "yet its implementation requests a value which cannot modify the this pointer.\n"
433  "in function "+parent->GetName(), 4, 3
434  );
435  }
436  else {
437  const auto &param=parameters[P_-ismember];
438 
439  //if not the repeating parameter
440  if(P_-ismember!=parameters.size()-1 || !repeatlast) {
441  //cannot be a reference as it is passed by value
442  ASSERT(!param.IsReference() || param.GetType()==Types::Variant(),
443  "Parameter #"+(String::From(P_-ismember+1)+", "+param.GetName())+" is declared as reference, "
444  "yet its implementation not\n"
445  "in function "+parent->GetName(), 4, 3
446  );
447 
448  //for the sake of clarity, if a function requires const, it should be marked as const
449  ASSERT(!param.IsConstant(),
450  "Parameter #"+(String::From(P_-ismember+1)+", "+param.GetName())+" is declared as constant, "
451  "yet its implementation is not const\n"
452  "in function "+parent->GetName(), 4, 3
453  );
454  }
455  //else std::vector<...> is allowed
456  }
457  }
458 
459  //**type check
460  //**
461  //this pointer
462  if(P_==0 && ismember) {
463  ASSERT(
464  (rtt.NormalType==parent->GetOwner().TypeInterface.NormalType),
465  "The declared type ("+parent->GetOwner().GetName()+", "+
467  "parameter #"+String::From(P_-ismember+1)+" does not match with the function type ("+
468  rtt.NormalType.Name()+")\n"+
469  "in function "+parent->GetName(), 4, 3
470  );
471  }
472  //repeating parameter
473  else if(P_-ismember==parameters.size()-1 && repeatlast) {
474  const auto &param=parameters[P_-ismember];
475 
476  TMP::RTTS *typeinf;
477  if(param.IsConstant()) {
478  if(param.IsReference()) {
479  typeinf=&param.GetType().TypeInterface.ConstPtrType;
480  }
481  else {
482  typeinf=&param.GetType().TypeInterface.ConstType;
483  }
484  }
485  else {
486  if(param.IsReference()) {
487  typeinf=&param.GetType().TypeInterface.PtrType;
488  }
489  else {
490  typeinf=&param.GetType().TypeInterface.NormalType;
491  }
492  }
493 
494  ASSERT(
495  (TMP::RTT<typename extractvector<T>::inner>()==*typeinf),
496  "The declared type ("+typeinf->Name()+") of "
497  "parameter #"+String::From(P_-ismember+1)+" does not match with the function type ("+
498  rtt.NormalType.Name()+")\n"+
499  "in function "+parent->GetName(), 4, 3
500  );
501  }
502  //regular parameters
503  else {
504  const auto &param=parameters[P_-ismember];
505 
506  ASSERT(
507  rtt.NormalType==param.GetType().TypeInterface.NormalType,
508  "The declared type ("+param.GetType().GetName()+", "+param.GetType().TypeInterface.NormalType.Name()+") of "
509  "parameter #"+(String::From(P_-ismember+1)+", "+param.GetName())+" does not match with the function type ("+
510  rtt.NormalType.Name()+")\n"
511  "in function "+parent->GetName(), 4, 3
512  );
513  }
514  }
515 
516  template<int ...S_>
517  void check(TMP::Sequence<S_...>) {
518  char dummy[] = {0, (checkparam<S_>(),'\0')...};
519  }
520 
521  virtual void dochecks(bool ismethod) override {
523 
524  ASSERT(traits::Arity-(parent->IsMember()&&!parent->IsStatic()) == parameters.size(),
525  "Number of function parameters ("+String::From(traits::Arity-(parent->IsMember()&&!parent->IsStatic()))+") "
526  "does not match with declared parameters ("+String::From(parameters.size())+")\n"
527  "in function "+parent->GetName(), 4, 3
528  );
529 
530  //check return type
531  //if void
532  if(std::is_same<typename traits::ReturnType, void>::value) {
533  //return type should be nullptr
534  ASSERT(
535  returntype==nullptr,
536  "This function variant expects a return type of "+
537  returntype->GetName()+"\n"
538  "in function "+parent->GetName(), 4, 3
539  );
540  }
541  else {
542  ASSERT(
543  returntype!=nullptr,
544  "Return type is marked as void. Supplied function's return type is :"+
545  Utils::GetTypeName<typename traits::ReturnType>()+
546  "in function "+parent->GetName(), 4, 3
547  );
548 
549  TMP::AbstractRTT<typename traits::ReturnType> returnrtt;
550 
551  //**return type check
552 
553  //returns a reference value
555  //in case of const
556  if(returnsconst) {
557  //can either return const ptr or const ref of the given type
558  ASSERT(
559  returntype->TypeInterface.ConstPtrType==returnrtt ||
561  "Return type of the function ("+returntype->GetName()+", "+
562  returntype->TypeInterface.ConstPtrType.Name()+") does not match "
563  "with its implementation ("+returnrtt.Name()+")"
564  "in function "+parent->GetName(), 4, 3
565  );
566  }
567  else {
568  //can either return non-const ptr or non-const ref of the given type
569  ASSERT(
570  returntype->TypeInterface.PtrType==returnrtt ||
571  returntype->TypeInterface.RefType==returnrtt,
572  "Return type of the function ("+returntype->GetName()+", "+
573  returntype->TypeInterface.PtrType.Name()+") does not match "
574  "with its implementation ("+returnrtt.Name()+")"
575  "in function "+parent->GetName(), 4, 3
576  );
577  }
578  }
579  //returns a value
580  else {
581  //in case of const
582  if(returnsconst) {
583  //should return const of that type, non-const can also be supported but
584  //no point in doing so
585  ASSERT(
586  returntype->TypeInterface.ConstType==returnrtt,
587  "Return type of the function ("+returntype->GetName()+", "+
588  returntype->TypeInterface.ConstType.Name()+") does not match "
589  "with its implementation ("+returnrtt.Name()+")"
590  "in function "+parent->GetName(), 4, 3
591  );
592  }
593  else {
594  //should return the type, const can also be supported but
595  //no point in doing so
596  ASSERT(
597  returntype->TypeInterface.NormalType==returnrtt,
598  "Return type of the function ("+returntype->GetName()+", "+
599  returntype->TypeInterface.NormalType.Name()+") does not match "
600  "with its implementation ("+returnrtt.Name()+")"
601  "in function "+parent->GetName(), 4, 3
602  );
603  }
604  }
605  }
606 
607  check(typename TMP::Generate<traits::Arity>::Type());
608  }
609 
610  F_ fn;
611  };
612 
613  template<class F_, class ...P_>
614  Scripting::Function::Overload *MapFunction(F_ fn, const Type *returntype, ParameterList parameters, P_ ...tags) {
615  return new MappedFunction<F_>(fn, returntype, std::move(parameters), tags...);
616  }
617 
618  template<class F_, class ...P_>
619  Scripting::Function::Overload *MapFunction(F_ fn, const Type *returntype, ParameterList parameters, bool stretchlast, bool repeatlast,
620  bool accessible, bool constant, bool returnsref, bool returnsconst, bool implicit) {
621  return new MappedFunction<F_>(fn, returntype, std::move(parameters), stretchlast, repeatlast, accessible,
622  constant, returnsref, returnsconst, implicit);
623  }
624 
625  template<class F_, class ...P_>
626  Scripting::Function::Overload *MapOperator(F_ fn, const Type *returntype, const Type *rhs) {
627  return new MappedFunction<F_>(fn, returntype, {
628  Scripting::Parameter("rhs", "Right hand side of the operator", rhs)
629  }, ConstTag);
630  }
631 
636  public:
638  template<class F_>
639  MappedOperator(const std::string &name, const std::string &help, const Type *parent,
640  const Type *returntype, const Type *rhs, F_ fn) :
641  Function( name, help, *parent, {}, Scripting::OperatorTag ) {
642  ASSERT(returntype, "Operators should have a return type", 1, 1);
643  ASSERT(parent, "Operators should belong a class", 1, 1);
644 
646  MapFunction(fn, returntype,
647  {
648  Scripting::Parameter("rhs", "Right hand side of the operator", rhs)
649  },
650  ConstTag
651  )
652  );
653  }
654 
655  MappedOperator(const std::string &name, const std::string &help, const Type *parent,
656  std::initializer_list<Function::Overload *> overloads) :
657  Function( name, help, *parent, {}, Scripting::OperatorTag) {
658 
659  for(auto overload : overloads) {
660  ASSERT(overload->HasReturnType(), "Operators should have a return type", 1, 1);
661  ASSERT(overload->IsConstant(), "Operators should be constant functions", 1, 1);
662  ASSERT(overload->Parameters.size()==1, "Operators should have a single parameter", 1, 1);
663 
664  Function::AddOverload(overload);
665  }
666 
667  }
668 
670  template<class F_>
671  void AddOverload(F_ fn, const Type *returntype, const Type *rhs) {
672  ASSERT(returntype, "Operators should have a return type", 1, 1);
673 
675  MapFunction(fn, returntype,
676  {
677  Scripting::Parameter("rhs",
678  "Right hand side of the operator", rhs
679  )
680  },
681  ConstTag
682  )
683  );
684  }
685 
686  private:
687  };
688 
692  #define MAP_COMPARE(opname, op, mappedtype, cpptype) \
693  new MappedOperator( #opname, \
694  "Compares two "#mappedtype" types.", mappedtype, \
695  Types::Bool(), mappedtype, [](cpptype l, cpptype r) { return l op r; } \
696  )
697 
701  template<class from_, class to_>
702  Scripting::Function::Overload *MapTypecast(Type *from, Type *to, bool implicit=true) {
703  if(implicit) {
704  return MapFunction(
705  [](from_ val) {
706  return to_(val);
707  }, to,
708  {
709  Parameter("value", "", from)
710  },
712  );
713  }
714  else {
715  return MapFunction(
716  [](from_ val) {
717  return to_(val);
718  }, to,
719  {
720  Parameter("value", "", from)
721  }
722  );
723  }
724  }
725 
726 
730  template<class from_, class to_>
731  Scripting::Function::Overload *MapDynamiccast(Type *from, Type *to, bool implicit=true) {
732  if(implicit) {
733  return MapFunction(
734  [](from_ &val) {
735  return dynamic_cast<to_&>(val);
736  }, to,
737  {
738  Parameter("value", "", from)
739  },
741  );
742  }
743  else {
744  return MapFunction(
745  [](from_ &val) {
746  return dynamic_cast<to_&>(val);
747  }, to,
748  {
749  Parameter("value", "", from)
750  }
751  );
752  }
753  }
754 
758  template<class from_, class to_>
759  Scripting::Function::Overload *MapConstDynamiccast(Type *from, Type *to, bool implicit=true) {
760  if(implicit) {
761  return MapFunction(
762  [](from_ &val) {
763  return dynamic_cast<to_&>(val);
764  }, to,
765  {
766  Parameter("value", "", from)
767  },
769  );
770  }
771  else {
772  return MapFunction(
773  [](from_ &val) {
774  return dynamic_cast<to_&>(val);
775  }, to,
776  {
777  Parameter("value", "", from)
778  }
779  );
780  }
781  }
782 
786  template<class from_, class to_>
787  Scripting::Function::Overload *MapStaticcast(Type *from, Type *to, bool implicit=true) {
788  if(implicit) {
789  return MapFunction(
790  [](const from_ &val) {
791  return static_cast<const to_&>(val);
792  }, to,
793  {
794  Parameter("value", "", from)
795  },
797  );
798  }
799  else {
800  return MapFunction(
801  [](const from_ &val) {
802  return static_cast<const to_&>(val);
803  }, to,
804  {
805  Parameter("value", "", from)
806  }
807  );
808  }
809  }
810 
814  template<class from_, class to_>
815  Scripting::Function::Overload *MapConstStaticcast(Type *from, Type *to, bool implicit=true) {
816  if(implicit) {
817  return MapFunction(
818  [](const from_ &val) {
819  return static_cast<const to_&>(val);
820  }, to,
821  {
822  Parameter("value", "", from)
823  },
825  );
826  }
827  else {
828  return MapFunction(
829  [](const from_ &val) {
830  return static_cast<const to_&>(val);
831  }, to,
832  {
833  Parameter("value", "", from)
834  }
835  );
836  }
837  }
838 
843  template<class C_, class T_>
845  protected:
846  using normaltype = typename std::remove_const<typename std::remove_pointer<T_>::type>::type;
847  using classptr = typename std::remove_pointer<C_>::type *;
848  using classbase = typename std::remove_pointer<C_>::type;
849 
850  enum {
851  istypeconst = std::is_const<typename std::remove_pointer<T_>::type>::value,
852  istypeptr = std::is_pointer<T_>::value,
853  };
854 
855  MappedROInstanceMember(T_ classbase::*member, const std::string &name, const std::string &help, const Type *type,
856  bool constant, bool ref, bool readonly) :
858  ASSERT(type, "Type cannot be nullptr", 1, 2);
860  " ("+type->TypeInterface.NormalType.Name()+") "
861  " does not match with c++ type: "+Utils::GetTypeName<normaltype>(), 1, 2);
862  ASSERT(constant==istypeconst, "Constness of "+name+" does not match with its implementation");
863  }
864 
865  template<class T2_=T_>
866  static typename std::enable_if<istypeptr, typename std::remove_pointer<T2_>::type>::type deref(const T2_ val) {
867  return *val;
868  }
869 
870  template<class T2_=T_>
871  static typename std::enable_if<!istypeptr, typename std::remove_pointer<T2_>::type>::type deref(const T2_ val) {
872  return val;
873  }
874 
875  template<class T2_=T_>
876  static typename std::enable_if<istypeptr, T2_>::type toptr(T2_ val) {
877  return val;
878  }
879 
880  template<class T2_=T_>
881  static typename std::enable_if<!istypeptr, T2_*>::type toptr(T2_ &val) {
882  return &val;
883  }
884 
885  template<class C2_=C_>
886  static typename std::enable_if<std::is_pointer<C2_>::value, const C2_>::type clstoptr(const C2_ val) {
887  return val;
888  }
889 
890  template<class C2_=C_>
891  static typename std::enable_if<!std::is_pointer<C2_>::value, const C2_*>::type clstoptr(const C2_ &val) {
892  return &val;
893  }
894 
895  template<class T2_=T_>
896  typename std::enable_if<std::is_copy_constructible<T2_>::value, Data>::type getnonref(Data &data) const {
897  return {GetType(), (const normaltype)deref(clstoptr(data.GetValue<const C_>())->*member), false, true};
898  }
899 
900  template<class T2_=T_>
901  typename std::enable_if<!std::is_copy_constructible<T2_>::value, Data>::type getnonref(Data &data) const {
902  return {};
903  }
904 
905  public:
907  MappedROInstanceMember(T_ classbase::*member, const std::string &name, const std::string &help,
908  const Type *type, bool constant=false) :
910  { }
911 
913 
914  protected:
915  virtual void typecheck(const Scripting::Type *type) const override final {
916  ASSERT(type->TypeInterface.NormalType.IsSameType<typename std::remove_pointer<C_>::type>(),
917  "The type of the parent does not match with the type "
918  "it has placed in.", 2, 2);
919  }
920 
921  virtual void set(Data &source, Data &value) const override {
922  }
923 
924  virtual Data get(Scripting::Data &data) const override {
925  // we dont need to return a pointer
926  if((constant || data.IsConstant()) && !data.IsReference() && std::is_copy_constructible<T_>::value) {
927  return getnonref(data);
928  }
929  else {
930  data.GetReference();
931  Data d;
932  if(data.IsConstant() || constant) {
933  d={GetType(), (const normaltype *)toptr(data.ReferenceValue<classptr>()->*member), true, true};
934  }
935  else {
936  d={GetType(), toptr(data.ReferenceValue<classptr>()->*member), true, false};
937  }
938 
939  d.SetParent(data);
940  return d;
941  }
942  }
943 
945  };
946 
950  template<class C_, class T_>
952  using classbase = typename std::remove_pointer<C_>::type;
953  public:
955  MappedInstanceMember(T_ classbase::*member, const std::string &name, const std::string &help, const Type *type, bool constant=false, bool ref=false) :
956  MappedROInstanceMember<C_, T_>(member, name, help, type, constant, ref, false)
957  {
958  if(ref) {
959  ASSERT(std::is_pointer<T_>::value, "Member "+name+" marked as reference but its source is not, should be a pointer");
960  }
961 
962  ASSERT(!constant || ref, "Non-reference constant instance members becomes readonly, choose a readonly embedder for "+name);
963  }
964 
965 
966  protected:
967  using classptr = typename std::remove_pointer<C_>::type *;
968 
969  template<class T2_=T_>
970  typename std::enable_if<std::is_pointer<T2_>::value, typename std::remove_pointer<T2_>::type>::type &getref(T2_ value) const {
971  return *value;
972  }
973 
974  template<class T2_=T_>
975  typename std::enable_if<!std::is_pointer<T2_>::value, T2_>::type &getref(T2_ &value) const {
976  return value;
977  }
978 
979  virtual void set(Data &source, Data &value) const override {
980  if(source.IsConstant()) {
981  throw ConstantException("Given item");
982  }
983 
984  if(value.IsConstant() && this->reference && !this->constant) {
985  throw ConstantException("Value for "+this->name, "Given value for "+this->name+" is constant");
986  }
987 
988  if(source.IsReference()) {
989  C_ *obj = source.ReferenceValue<classptr>();
990  if(this->reference) {
991  if(value.IsConstant()) {
992  obj->*this->member = value.ReferenceValue<T_>();
993  }
994  else {
995  obj->*this->member = value.ReferenceValue<const T_>();
996  }
997  }
998  else {
999  if(value.IsConstant()) {
1000  obj->*this->member = this->deref(value.GetValue <const T_>());
1001  }
1002  else {
1003  obj->*this->member = this->deref(value.GetValue <T_>());
1004  }
1005  }
1006  }
1007  else {
1008  C_ obj = source.GetValue<C_>();
1009 
1010  if(this->reference) { //T_ is sure to be ptr
1011  if(value.IsConstant()) {
1012  obj.*this->member = value.ReferenceValue<T_>();
1013  }
1014  else {
1015  obj.*this->member = value.ReferenceValue<const T_>();
1016  }
1017  }
1018  else {
1019  if(value.IsConstant()) { //T_ may or may not be a ptr, if its a ptr, its value will be changed
1020  getref(obj.*this->member) = value.GetValue <const T_>();
1021  }
1022  else {
1023  getref(obj.*this->member) = value.GetValue <T_>();
1024  }
1025  }
1026 
1027  source={source.GetType(), obj};
1028  }
1029  }
1030  };
1031 
1040  protected:
1043 
1044 
1045  template <class F_>
1046  MappedROInstanceMember_Function(F_ reader, const std::string &name, const std::string &help, const Type *type,
1047  const Type *parent, bool isconstfn, bool isreffn, bool constant, bool ref, bool readonly) :
1048  InstanceMember(name, help, *type, constant, ref, readonly), fn("", "", parent, {}) {
1049  ASSERT(type, "Type cannot be nullptr", 1, 2);
1050 
1051  ASSERT(parent, "Parent cannot be nullptr", 1, 2);
1052 
1053  ASSERT(type->IsReferenceType() || constant || isreffn,
1054  "Instance member implies that it could be changed, yet its implementation does not allow "
1055  "such use. For instance member "+name);
1056 
1057  ASSERT(!ref || isreffn || type->IsReferenceType(),
1058  "Instance member is a reference, yet its implementation is not."
1059  "For instance member "+name);
1060 
1061  readerfn=MapFunction(reader, type, {}, false, false, true, isconstfn, isreffn, constant, false);
1063  }
1064 
1065  public:
1079  template <class F_>
1080  MappedROInstanceMember_Function(F_ reader, const std::string &name, const std::string &help,
1081  const Type *type, const Type *parent, bool isconstfn, bool isreffn, bool constant=false) :
1082  MappedROInstanceMember_Function(reader, name, help, type, parent, isconstfn, isreffn, constant, false, true)
1083  { }
1084 
1086 
1087  protected:
1088  virtual void typecheck(const Type *type) const override {
1089  ASSERT(type == fn.GetOwner(), "Declared and placed owners do not match");
1090  }
1091 
1092  virtual void set(Data &source, Data &value) const override {
1093  }
1094 
1095  virtual Data get(Scripting::Data &data) const override {
1096  return VirtualMachine::Get().ExecuteFunction(&fn, {data}, false);
1097  }
1098  };
1099 
1110  public:
1124  template <class F1_, class F2_>
1125  MappedInstanceMember_Function(F1_ reader, F2_ writer, const std::string &name, const std::string &help,
1126  const Type *type, const Type *parent, bool isconstfn, bool isreffn, bool ref, bool isgetconst, bool issetconst=false) :
1127  MappedROInstanceMember_Function(reader, name, help, type, parent, isconstfn, isreffn, isgetconst, ref, false)
1128  {
1129  writerfn=MapFunction(
1130  writer, nullptr, {
1131  Parameter("value", "", type, Data::Invalid(), OptionList(), ref, issetconst, false, false)
1132  }, false, false, true, false, false, false, false
1133  );
1134  this->fn.AddOverload(writerfn);
1135  }
1136 
1137  protected:
1138  virtual void set(Data &source, Data &value) const override {
1139  VirtualMachine::Get().ExecuteFunction(&this->fn, {source, value}, false);
1140  }
1141  };
1142 
1146  template<class F_>
1147  InstanceMember *MapFunctionToInstanceMember(F_ reader, const std::string &name, const std::string &help,
1148  const Type *membertype, const Type *parenttype) {
1149  return new MappedROInstanceMember_Function(reader, name, help, membertype, parenttype, true, false, true);
1150  }
1151 
1152  template<class T_>
1154  protected:
1155  using normaltype = typename std::remove_const<typename std::remove_pointer<T_>::type>::type;
1156 
1157  enum {
1158  istypeconst = std::is_const<typename std::remove_pointer<T_>::type>::value,
1159  istypeptr = std::is_pointer<T_>::value,
1160  };
1161 
1162  MappedROStaticDataMember(T_ value, const std::string &name, const std::string &help, const Type *type,
1163  bool isconstant, bool ref, bool readonly) :
1165  {
1166  ASSERT(type, "Type cannot be nullptr", 1, 2);
1167  }
1168 
1169  template<class T2_=T_>
1170  typename std::enable_if<std::is_copy_constructible<T2_>::value, Data>::type getnonref() {
1171  return {GetType(), (const T_)value, false, true};
1172  }
1173 
1174  template<class T2_=T_>
1175  typename std::enable_if<!std::is_copy_constructible<T2_>::value, Data>::type getnonref() {
1176  return {};
1177  }
1178 
1179  public:
1183  MappedROStaticDataMember(T_ value, const std::string &name, const std::string &help, const Type *type,
1184  bool isconstant=false) :
1186  {
1187  }
1188 
1190 
1192  T_ GetValue() const {
1193  return value;
1194  }
1195 
1197  T_ &GetValue() {
1198  return value;
1199  }
1200 
1201  protected:
1202 
1203  virtual Data get() const override {
1204  // we dont need to return a pointer
1205  if(constant && !type->IsReferenceType() && !istypeptr && std::is_copy_constructible<T_>::value) {
1206  return getnonref();
1207  }
1208  else {
1209  Data d;
1210  if(constant) {
1211  if(istypeptr) {
1212  d={GetType(), (const T_)value, true, true};
1213  }
1214  else {
1215  d={GetType(), (const T_ *)&(value), true, true};
1216  }
1217  }
1218  else {
1219  if(istypeptr) {
1220  d={GetType(), (value), true, false};
1221  }
1222  else {
1223  d={GetType(), &(value), true, false};
1224  }
1225  }
1226 
1227  return d;
1228  }
1229  }
1230 
1231  virtual void set(Data &source, Data &value) const override {
1232  }
1233 
1234  T_ value;
1235  };
1236 
1237  template<class T_>
1239  public:
1243  MappedStaticDataMember(T_ value, const std::string &name, const std::string &help, const Type *type,
1244  bool constant=false, bool ref=false) :
1245  MappedROStaticDataMember<T_>(value, name, help, type, constant, ref, false)
1246  {
1247  if(ref) {
1248  ASSERT(std::is_pointer<T_>::value, "Member "+name+" marked as reference but its source is not, should be a pointer");
1249  }
1250 
1251  ASSERT(!constant || ref, "Non-reference constant instance members becomes readonly, choose a readonly embedder for "+name);
1252  }
1253 
1254 
1255  protected:
1256  template<class T2_=T_>
1257  typename std::enable_if<std::is_pointer<T2_>::value, typename std::remove_pointer<T2_>::type>::type &getref() {
1258  return *(this->value);
1259  }
1260 
1261  template<class T2_=T_>
1262  typename std::enable_if<!std::is_pointer<T2_>::value, T2_>::type &getref() {
1263  return this->value;
1264  }
1265 
1266  virtual void set(Data &value) const override {
1267 
1268  if(value.IsConstant() && this->reference && !this->constant) {
1269  throw ConstantException("Value for "+this->name, "Given value for "+this->name+" is constant");
1270  }
1271 
1272  if(this->reference) {
1273  if(value.IsConstant()) {
1274  this->value = value.ReferenceValue<T_>();
1275  }
1276  else {
1277  this->value = value.ReferenceValue<const T_>();
1278  }
1279  }
1280  else {
1281  if(value.IsConstant()) {
1282  getref() = value.GetValue <const T_>();
1283  }
1284  else {
1285  getref() = value.GetValue <T_>();
1286  }
1287  }
1288  }
1289  };
1290 
1295  template <
1296  class T_,
1297  StringFromFn<T_> ToString_,
1298  ParseFn<T_> Parse_
1299  >
1300  class MappedValueType : public Type {
1301  public:
1302  MappedValueType(const std::string &name, const std::string &help, const T_ &def) :
1303  Type(name, help, def, new TMP::AbstractRTTC<T_>(), false)
1304  {
1305  addcopyconst<T_>();
1306  }
1307 
1308  MappedValueType(const std::string &name, const std::string &help) : MappedValueType(name, help, T_()) {
1309  }
1310 
1311  template<class ...P_>
1313  ASSERT(sizeof...(P_)==params.size(), "Number of parameters does not match");
1314  AddConstructors({
1315  MapFunction(
1316  [](P_... args) {
1317  return T_(args...);
1318  },
1319  *this,
1320  params
1321  )
1322  });
1323  }
1324 
1327  virtual std::string ToString(const Data &data) const override {
1328  return ToString_(data.GetValue<T_>());
1329  }
1330 
1332  virtual Data Parse(const std::string &str) const override {
1333  return Data(this, Parse_(str));
1334  }
1335 
1336  virtual void Assign(Data &l, const Data &r) const override {
1337  if(l.GetType()!=r.GetType()) {
1338  throw CastException(r.GetType().GetName(), l.GetType().GetName());
1339  }
1340 
1341  if(l.IsReference()) {
1342  if(l.IsConstant()) {
1343  throw ConstantException("");
1344  }
1345 
1346  *(l.ReferenceValue<T_*>())=r.GetValue<T_>();
1347  }
1348  else {
1349  l={l.GetType(), r.GetValue<T_>()};
1350  }
1351  }
1352 
1353  protected:
1354  virtual void deleteobject(const Data &obj) const override {
1355  ASSERT(obj.IsReference(), "Deleting a non reference");
1356 
1357  T_ *ptr;
1358  if(obj.IsConstant()) {
1359  //force to non-const
1360  ptr=const_cast<T_*>(obj.ReferenceValue<const T_*>());
1361  }
1362  else {
1363  ptr=obj.ReferenceValue<T_*>();
1364  }
1365  if(ptr!=nullptr) {
1366  delete ptr;
1367  }
1368  }
1369 
1370  bool compare(const Data &l, const Data &r) const override {
1371  return l.GetValue<T_>()==r.GetValue<T_>();
1372  }
1373 
1374  template<class O_>
1375  typename std::enable_if<std::is_copy_constructible<O_>::value, void>::type
1377  //automatic copy constructor
1378  AddConstructors({
1379  MapFunction(
1380  [](O_ o) {
1381  return T_(o);
1382  },
1383  *this,
1384  {
1385  Parameter("value", "The value to be copied", this)
1386  }
1387  )
1388  });
1389  }
1390  template<class O_>
1391  typename std::enable_if<!std::is_copy_constructible<O_>::value, void>::type
1393  }
1394  };
1395 
1401  template <
1402  class T_,
1403  std::string(*ToString_)(const T_ &),
1404  T_*(*Parse_)(const std::string &)
1405  >
1407  public:
1408  MappedReferenceType(const std::string &name, const std::string &help, T_ *def) :
1409  Type(name, help, def, new TMP::AbstractRTTC<T_>(), true)
1410  {
1411  addcopyconst<T_>();
1412  }
1413 
1414  MappedReferenceType(const std::string &name, const std::string &help) : MappedReferenceType(name, help, nullptr) {
1415  }
1416 
1417 
1420  virtual std::string ToString(const Data &data) const override {
1421  if(data.IsConstant()) {
1422  if(data.ReferenceValue<const T_*>()==nullptr) return "<null>";
1423  return ToString_(*data.ReferenceValue<const T_*>());
1424  }
1425  else {
1426  if(data.ReferenceValue<T_*>()==nullptr) return "<null>";
1427  return ToString_(*data.ReferenceValue<T_*>());
1428  }
1429  }
1430 
1431  template<class ...P_>
1433  ASSERT(sizeof...(P_)==params.size(), "Number of parameters does not match");
1434  AddConstructors({
1435  MapFunction(
1436  [](P_... args) {
1437  auto obj=new T_(args...);
1438  VirtualMachine::Get().References.Register(obj);
1439 
1440  return obj;
1441  },
1442  *this,
1443  params
1444  )
1445  });
1446  }
1447 
1449  virtual Data Parse(const std::string &str) const override {
1450  return Data(this, Parse_(str));
1451  }
1452 
1453  virtual void Assign(Data &l, const Data &r) const override {
1454  }
1455 
1456  protected:
1457  virtual void deleteobject(const Data &obj) const override {
1458  T_ *ptr;
1459  if(obj.IsConstant()) {
1460  //force to non-const
1461  ptr=const_cast<T_*>(obj.ReferenceValue<const T_*>());
1462  }
1463  else {
1464  ptr=obj.ReferenceValue<T_*>();
1465  }
1466  if(ptr!=nullptr) {
1467  delete ptr;
1468  }
1469  }
1470 
1471  template<class O_>
1472  typename std::enable_if<std::is_copy_constructible<O_>::value, void>::type
1474  //automatic copy constructor
1475  AddConstructors({
1476  MapFunction(
1477  [](const O_ *o) {
1478  auto obj=new T_(*o);
1480 
1481  return obj;
1482  },
1483  *this,
1484  {
1485  Parameter("value", "The value to be copied", this, ReferenceTag, ConstTag)
1486  }
1487  )
1488  });
1489  }
1490  template<class O_>
1491  typename std::enable_if<!std::is_copy_constructible<O_>::value, void>::type
1493  }
1494  };
1495 
1496 
1500  template <class T_>
1501  struct InternalReferenceType {
1502  static Type *type;
1503  };
1504 
1505  template <class T_>
1506  Type *InternalReferenceType<T_>::type = new MappedReferenceType<T_, &ToEmptyString<T_>>("", "");
1507 
1510  template <class T_>
1511  struct InternalValueType {
1512  static Type *type;
1513  };
1514 
1515  template <class T_>
1516  Type *InternalValueType<T_>::type = new MappedValueType<T_>("", "");
1517 
1518  template <class R_>
1519  struct ExtractFromHelper {
1520  R_ operator()(const Data &d) const {
1521  return d.GetValue<R_>();
1522  }
1523  };
1524 
1525  template <class R_>
1526  struct ExtractFromHelper<R_*> {
1527  R_ *operator()(const Data &d) const {
1528  return d.ReferenceValue<R_*>();
1529  }
1530  };
1531 
1532  template <class R_>
1533  struct ExtractFromHelper<R_&> {
1534  R_ &operator()(const Data &d) const {
1535  return d.ReferenceValue<R_&>();
1536  }
1537  };
1538 
1539  template <>
1540  struct ExtractFromHelper<void> {
1541  void operator()(const Data &d) const {
1542  ASSERT(!d.IsValid(), "There is valid data in even though there shouldn't be.");
1543  }
1544  };
1545 
1546  template <class R_>
1547  R_ ExtractFromData(const Data &d) {
1548  ExtractFromHelper<R_> h;
1549  return h(d);
1550  }
1551 
1553 
1560  template <class E_, class O_, class R_, class ...P_>
1562  public:
1563  using TokenType = decltype(std::declval<E_>().Register(std::function<void()>()));
1564  std::map<TokenType, const Scripting::Function *> unregistertokens;
1565 
1566  private:
1567 
1568  template<class T_, class ...Params_>
1569  void constargs(int index, std::vector<Data> &ret, const std::vector<Parameter> params, T_ arg, Params_&& ...rest) {
1570  auto param=params[index];
1571  ret.push_back(Data(param.GetType(), arg, param.IsReference(), param.IsConstant()));
1572  constargs(index+1, ret, params, std::forward(rest)...);
1573  }
1574 
1575  void constargs(int index, std::vector<Data> &ret, const std::vector<Parameter> params) {}
1576 
1577  R_ callfn(const Scripting::Function *fn, std::vector<Data> args, Function::Overload *single) {
1578  using namespace Scripting;
1579 
1580  auto &vm=VirtualMachine::Get();
1581 
1582  //try with full arguments
1583  if(!single || single->Parameters.size()==args.size()-(fn->IsMember()&&!fn->IsStatic())) {
1584  try {
1585  return ExtractFromData<R_>(vm.ExecuteFunction(fn, args, false));
1586  }
1587  catch(SymbolNotFoundException &) {
1588  }
1589  }
1590 
1591  //empty one, if this fails, execution will fail
1592  return ExtractFromData<R_>(vm.ExecuteFunction(fn, {}, false));
1593  }
1594 
1595 
1596  template<class OO_=O_>
1597  typename std::enable_if<!std::is_same<OO_, void>::value, R_>::type
1598  callfn(O_& obj, const Scripting::Function *fn, std::vector<Data> args, Function::Overload *single) {
1599  auto &vm=VirtualMachine::Get();
1600 
1601  //try with object first if exists
1602  if(this->parenttype && (!single || single->Parameters.size()==args.size()+1-(fn->IsMember()&&!fn->IsStatic()))) {
1603  args.insert(args.begin(), Data(this->parenttype, &obj, true, std::is_const<O_>::value));
1604 
1605  try {
1606  return ExtractFromData<R_>(vm.ExecuteFunction(fn, args, false));
1607  }
1608  catch(SymbolNotFoundException &) {
1609  args.erase(args.begin());
1610  }
1611  }
1612 
1613  //if not call the caller without the object
1614  return callfn(fn, args, single);
1615  }
1616 
1617  template<class OO_=O_>
1618  typename std::enable_if<std::is_same<OO_, void>::value, TokenType>::type
1619  registerfn(E_ *ev, const Scripting::Function *fn) {
1620 
1621  bool found=false;
1622  for(auto &ovs : {&fn->Overloads, &fn->Methods}) {
1623  for(auto &ov : *ovs) {
1624  if(ov.Parameters.size()==sizeof...(P_) || ov.Parameters.size()==0) {
1625  found=true;
1626  break;
1627  }
1628  }
1629  if(found) break;
1630  }
1631 
1632  if(!found) throw ParameterError("No matching overload for the event is found.");
1633  //make sure that the fn stays alive
1634  auto &vm=VirtualMachine::Get();
1635  vm.References.Increase((void*)fn);
1636 
1637  auto tok=ev->Register([fn,this](P_&& ...args) {
1638  //prepare parameters
1639  std::vector<Data> pars;
1640  constargs(0, pars, parameters, std::forward<P_...>(args)...);
1641 
1642  //single overload means easy way out
1643  Function::Overload *overload=nullptr;
1644  if(fn->Overloads.GetSize()+fn->Methods.GetSize()) {
1645  if(fn->Overloads.GetSize())
1646  overload=&fn->Overloads[0];
1647  else
1648  overload=&fn->Methods[0];
1649  }
1650 
1651  return callfn(fn, pars, overload);
1652  });
1653 
1654  unregistertokens[tok]=fn;
1655 
1656  return tok;
1657  }
1658 
1659  template<class OO_=O_>
1660  typename std::enable_if<!std::is_same<OO_, void>::value, TokenType>::type
1661  registerfn(E_ *ev, const Scripting::Function *fn) {
1662  using namespace Scripting;
1663 
1664  bool found=false;
1665  for(auto &ovs : {&fn->Overloads, &fn->Methods}) {
1666  for(auto &ov : *ovs) {
1667  if(ov.Parameters.size()==sizeof...(P_) || ov.Parameters.size()==sizeof...(P_)+1 || ov.Parameters.size()==0) {
1668  found=true;
1669  break;
1670  }
1671  }
1672  if(found) break;
1673  }
1674 
1675  if(!found) throw ParameterError("No matching overload for the event is found.");
1676 
1677  //make sure that the fn stays alive
1678  auto &vm=VirtualMachine::Get();
1679  vm.References.Increase((void*)fn);
1680 
1681  auto tok=ev->Register([fn,this](O_ &obj, P_&& ...args) {
1682  //prepare parameters
1683  std::vector<Data> pars;
1684  constargs(0, pars, parameters, std::forward<P_...>(args)...);
1685 
1686  //single overload means easy way out
1687  Function::Overload *overload=nullptr;
1688  if(fn->Overloads.GetSize()+fn->Methods.GetSize()) {
1689  if(fn->Overloads.GetSize())
1690  overload=&fn->Overloads[0];
1691  else
1692  overload=&fn->Methods[0];
1693  }
1694 
1695  return callfn(obj, fn, pars, overload);
1696  });
1697 
1698  unregistertokens[tok]=fn;
1699  return tok;
1700  }
1701 
1702  using registerfnsig = TokenType(MappedEventType::*)(E_*,const Scripting::Function*);
1703 
1704  public:
1705  MappedEventType(const std::string &name, const std::string &help,
1706  const ParameterList &parameters={}, const Type *parenttype=nullptr, const Type *ret=nullptr) :
1707  EventType(name, help, (E_*)nullptr, new TMP::AbstractRTTC<E_>(), ret, parameters), parenttype(parenttype)
1708  {
1709  using namespace Gorgon::Scripting;
1710  AddMembers({
1711  new Scripting::Function("Fire",
1712  "Fires this event",
1713  this, {
1714  MapFunction(
1715  &E_::operator(), ret, parameters
1716  )
1717  }
1718  ),
1719  new Scripting::Function("Register",
1720  "Registers a new handler to this event",
1721  this, {
1722  MapFunction(
1723  [this](E_ *ev, const Scripting::Function *fn) {
1724  return this->registerfn(ev,fn);
1725  },
1726  InternalValueType<TokenType>::type, {
1727  Parameter("Handler",
1728  "The function to handle the event",
1729  Types::Function(),
1730  ConstTag
1731  )
1732  }
1733  )
1734  }
1735  ),
1736  new Scripting::Function("Unregister",
1737  "This function unregisters a given event handler token.",
1738  this, {
1739  MapFunction(
1740  [this](E_ *event, TokenType token) {
1741  event->Unregister(token);
1742  auto &vm=VirtualMachine::Get();
1743  vm.References.Decrease(Data(Types::Function(), this->unregistertokens[token], true, true));
1744  this->unregistertokens.erase(token);
1745  },
1746  nullptr, {
1747  Parameter("Token",
1748  "Event handler token",
1749  InternalValueType<TokenType>::type
1750  )
1751  }
1752  )
1753  }
1754  ),
1755 
1756  });
1757  }
1758 
1759 
1760  virtual std::string ToString(const Gorgon::Scripting::Data&) const override {
1761  return "Event object";
1762  }
1763 
1764  virtual Data Parse(const std::string&) const override {
1765  throw std::runtime_error("Events cannot be parsed from a string");
1766  }
1767 
1768  protected:
1769 
1770  virtual void deleteobject(const Gorgon::Scripting::Data &data) const override {
1771  if(data.IsConstant()) {
1772  throw Scripting::ConstantException("Given data");
1773  }
1774  delete data.GetValue<E_ *>();
1775  }
1776 
1777 
1778  private:
1779  const Type *parenttype;
1780  };
1781 
1785  template <class E_>
1787  public:
1790  MappedStringEnum(const std::string& name, const std::string& help,
1791  const std::vector<std::pair<std::string, std::string>> &strings, E_ defval=E_(), bool binary=false) :
1792  EnumType(name, help, defval, new TMP::AbstractRTTC<E_>()) {
1793  for(auto &s : strings) {
1794  this->add({s.first, s.second, String::Parse<E_>(s.first)});
1795  }
1796 
1797  //copy and default constructor
1798  AddConstructors({
1799  MapFunction(
1800  [](E_ e) { return e; }, this,
1801  { Parameter("value", "The value to be copied", this) }
1802  ),
1803  MapFunction(
1804  [defval]() { return defval; }, this,
1805  { }
1806  ),
1807  });
1808 
1809  AddMember(MAP_COMPARE(=, ==, this, E_));
1810 
1811  if(binary) {
1812  AddMembers({
1813  new Scripting::Function("binary", "Returns binary form of this enumeration",
1814  this, {
1815  MapFunction(
1816  [](E_ e) -> std::string {
1817  unsigned val=(unsigned)e;
1818  unsigned digits=int(std::log2((double)val)+1);
1819  std::string ret(' ', digits);
1820  for(unsigned i=0;i<digits;i++) {
1821  ret[digits-i-1]=val&1 ? '1':'0';
1822  val=val>>1;
1823  }
1824 
1825  return ret;
1826  }, Types::String(), {}, ConstTag
1827  ),
1828  MapFunction(
1829  [](E_ e, unsigned digits) -> std::string {
1830  unsigned val=(unsigned)e;
1831  std::string ret(' ', digits);
1832  for(unsigned i=0;i<digits;i++) {
1833  ret[digits-i-1]=val&1 ? '1':'0';
1834  val=val>>1;
1835  }
1836 
1837  return ret;
1838  }, Types::String(), {
1839  Parameter("digits", "Number of digits to be considered", Types::Unsigned())
1840  }, ConstTag
1841  )
1842  }
1843  ),
1844 
1845  new MappedOperator("with", "Combines two enumeration entries",
1846  this, this, this,
1847  [](E_ l, E_ r) -> E_ {
1848  return (E_)((unsigned)l|(unsigned)r);
1849  }
1850  ),
1851  });
1852  }
1853  }
1854 
1857  MappedStringEnum(const std::string& name, const std::string& help, E_ defval=E_(), bool binary=false) :
1858  MappedStringEnum(name, help, {}, defval, binary) {
1859  for (E_ e : Gorgon::Enumerate<E_>()) {
1860  this->add({String::From(e), "", Any(e)});
1861  }
1862  }
1863 
1864  virtual std::string ToString(const Data &d) const {
1865  return String::From(d.GetValue<E_>());
1866  }
1867 
1868  virtual Data Parse(const std::string &s) const {
1869  return {this, String::Parse<E_>(s)};
1870  }
1871 
1872  virtual void Assign(Data &l, const Data &r) const override {
1873  if(l.GetType()!=r.GetType()) {
1874  throw CastException(r.GetType().GetName(), l.GetType().GetName());
1875  }
1876 
1877  if(l.IsReference()) {
1878  if(l.IsConstant()) {
1879  throw ConstantException("");
1880  }
1881 
1882  *(l.ReferenceValue<E_*>())=r.GetValue<E_>();
1883  }
1884  else {
1885  l={l.GetType(), r.GetValue<E_>()};
1886  }
1887  }
1888 
1889  protected:
1890  virtual bool compare(const Data& l, const Data& r) const {
1891  return l.GetValue<E_>() == r.GetValue<E_>();
1892  }
1893 
1894  virtual void deleteobject(const Data &obj) const override {
1895  ASSERT(obj.IsReference(), "Deleting a non reference");
1896 
1897  E_ *ptr;
1898  if(obj.IsConstant()) {
1899  //force to non-const
1900  ptr=const_cast<E_*>(obj.ReferenceValue<const E_*>());
1901  }
1902  else {
1903  ptr=obj.ReferenceValue<E_*>();
1904  }
1905  if(ptr!=nullptr) {
1906  delete ptr;
1907  }
1908  }
1909  };
1910 
1911  template<class T_, class I_>
1912  void MapDynamicInheritance(Type *type, Type *inherited) {
1913  ASSERT(type && inherited, "Inheritance types cannot be nullptr");
1914 
1915  type->AddInheritance(
1916  *inherited,
1917  [=](Data d) -> Data {
1918  if(d.IsConstant())
1919  return Data(*type,dynamic_cast<const T_*>(d.ReferenceValue<const I_*>()), true, true);
1920  else
1921  return Data(*type,dynamic_cast<T_*>(d.ReferenceValue<I_*>()), true, false);
1922  },
1923  [=](Data d) -> Data {
1924  if(d.IsConstant())
1925  return Data(*inherited,dynamic_cast<const I_*>(d.ReferenceValue<const T_*>()), true, true);
1926  else
1927  return Data(*inherited,dynamic_cast<I_*>(d.ReferenceValue<T_*>()), true, false);
1928  }
1929  );
1930  }
1931 
1932 } }
Gorgon::Scripting::MappedInstanceMember_Function
This class allows mapping of a data member to c++ function data member.
Definition: Embedding.h:1108
Gorgon::Scripting::Function::Overload::dochecks
virtual void dochecks(bool ismethod)
This function should perform validity checks on the variant.
Definition: Reflection.cpp:295
Gorgon::Scripting::InstanceMember::GetType
const Type & GetType() const
Returns the type of this data member.
Definition: Reflection.h:1003
Gorgon::Scripting::MappedReferenceType::deleteobject
virtual void deleteobject(const Data &obj) const override
Definition: Embedding.h:1457
Gorgon::Scripting::MappedROStaticDataMember::value
T_ value
Definition: Embedding.h:1234
Gorgon::Scripting::MappedROStaticDataMember::MappedROStaticDataMember
MappedROStaticDataMember(T_ value, const std::string &name, const std::string &help, const Type *type, bool isconstant, bool ref, bool readonly)
Definition: Embedding.h:1162
Gorgon::Scripting::Function::AddOverload
virtual void AddOverload(Overload &overload)
Adds the given overload to this function after performing necessary checks.
Definition: Reflection.h:881
Gorgon::Scripting::MapDynamiccast
Scripting::Function::Overload * MapDynamiccast(Type *from, Type *to, bool implicit=true)
Maps a constructor for type casting, works for polymorphic types.
Definition: Embedding.h:731
Gorgon::Scripting::MappedEventType::unregistertokens
std::map< TokenType, const Scripting::Function * > unregistertokens
Definition: Embedding.h:1564
Gorgon::Scripting::MappedROStaticDataMember::GetValue
T_ & GetValue()
Returns the value stored in this data.
Definition: Embedding.h:1197
Gorgon::Scripting::MapStaticcast
Scripting::Function::Overload * MapStaticcast(Type *from, Type *to, bool implicit=true)
Maps a constructor for type casting, works for reference types.
Definition: Embedding.h:787
Gorgon::String::From
std::enable_if< decltype(gorgon__enum_tr_loc(T_()))::isupgradedenum, std::string >::type From(const T_ &e)
Definition: Enum.h:303
Gorgon::TMP::RTTH::RefType
RTTS & RefType
Definition: TMP.h:375
Gorgon::Resource::GID::Data
constexpr Type Data
Data resource.
Definition: GID.h:164
Gorgon::Scripting::MappedValueType::MappedValueType
MappedValueType(const std::string &name, const std::string &help)
Definition: Embedding.h:1308
Gorgon::Scripting::MappedInstanceMember::getref
std::enable_if< std::is_pointer< T2_ >::value, typename std::remove_pointer< T2_ >::type >::type & getref(T2_ value) const
Definition: Embedding.h:970
Gorgon::TMP::RTTH::ConstPtrType
RTTS & ConstPtrType
Definition: TMP.h:375
Gorgon::Scripting::MappedInstanceMember::set
virtual void set(Data &source, Data &value) const override
This function should perform set operation.
Definition: Embedding.h:979
Gorgon::Scripting::MappedROInstanceMember_Function::MappedROInstanceMember_Function
MappedROInstanceMember_Function(F_ reader, const std::string &name, const std::string &help, const Type *type, const Type *parent, bool isconstfn, bool isreffn, bool constant=false)
Constructs a new MappedROInstanceMember_Function.
Definition: Embedding.h:1080
Gorgon::Scripting::MappedValueType::compare
bool compare(const Data &l, const Data &r) const override
Definition: Embedding.h:1370
Gorgon::Scripting::MappedValueType::addcopyconst
std::enable_if< std::is_copy_constructible< O_ >::value, void >::type addcopyconst()
Definition: Embedding.h:1376
Gorgon::Scripting::MappedStaticDataMember::set
virtual void set(Data &value) const override
Definition: Embedding.h:1266
Gorgon::Scripting::OperatorTag
@ OperatorTag
Makes a function operator.
Definition: Reflection.h:92
Gorgon::Scripting::MappedROInstanceMember_Function::~MappedROInstanceMember_Function
virtual ~MappedROInstanceMember_Function()
Definition: Embedding.h:1085
Gorgon::Scripting::MappedValueType::MapConstructor
void MapConstructor(ParameterList params)
Definition: Embedding.h:1312
Gorgon::Scripting::ReferenceCounter::Register
void Register(const Data &data)
Registers a new object of reference counting, this will set reference count to one.
Definition: Runtime.h:24
Gorgon::Scripting::Type::AddMembers
virtual void AddMembers(std::initializer_list< StaticMember * > newmembers) override
Adds a list of static members to this type.
Definition: Reflection.h:1228
Gorgon::Scripting::Data::ReferenceValue
std::enable_if< std::is_pointer< T_ >::value, T_ >::type ReferenceValue() const
Returns the value of this data in the requested format.
Definition: Data.h:112
Gorgon::Scripting::MappedROStaticDataMember::~MappedROStaticDataMember
virtual ~MappedROStaticDataMember()
Definition: Embedding.h:1189
Gorgon::Scripting::Type::TypeInterface
TMP::RTTH & TypeInterface
Type interface used for this type.
Definition: Reflection.h:1414
Gorgon::Any
This class can hold any other information providing type erasure.
Definition: Any.h:32
Gorgon::Scripting::MappedOperator::AddOverload
void AddOverload(F_ fn, const Type *returntype, const Type *rhs)
Adds a new operator overload.
Definition: Embedding.h:671
Gorgon::Scripting::Function::Overload::IsConstant
bool IsConstant() const
Returns whether this function is a constant.
Definition: Reflection.h:635
Gorgon::Scripting::VirtualMachine::References
ReferenceCounter References
This system allows objects of automatic lifetime.
Definition: VirtualMachine.h:222
Gorgon::Scripting::MappedReferenceType::MapConstructor
void MapConstructor(ParameterList params)
Definition: Embedding.h:1432
Gorgon::Scripting::EventType::parameters
ParameterList parameters
Parameters that every event handler should accept.
Definition: Reflection.h:1530
Reflection.h
Gorgon::Scripting::StaticDataMember::reference
bool reference
This instance member is a reference.
Definition: Reflection.h:503
Gorgon::Scripting::MappedStringEnum::deleteobject
virtual void deleteobject(const Data &obj) const override
This function should delete the given object.
Definition: Embedding.h:1894
Gorgon::Scripting::Data::GetValue
std::enable_if<!std::is_pointer< T_ >::value, const typename std::remove_reference< T_ >::type & >::type GetValue() const
Returns the value of this data in the requested format.
Definition: Data.h:57
Gorgon::Scripting::Function::Overload::returntype
const Type * returntype
Return type of this function variant. If nullptr this function does not return a value.
Definition: Reflection.h:739
Gorgon::Input::Keyboard::Keycodes::T
constexpr Key T
Definition: Keyboard.h:99
Gorgon::Scripting::MappedReferenceType::addcopyconst
std::enable_if<!std::is_copy_constructible< O_ >::value, void >::type addcopyconst()
Definition: Embedding.h:1492
Gorgon::Scripting::MappedROInstanceMember::normaltype
typename std::remove_const< typename std::remove_pointer< T_ >::type >::type normaltype
Definition: Embedding.h:846
Gorgon::Scripting::MappedEventType::TokenType
decltype(std::declval< E_ >().Register(std::function< void()>())) TokenType
Definition: Embedding.h:1563
Gorgon::Scripting::Data
Data describes a piece of data.
Definition: Data.h:22
Gorgon::Scripting::MappedROInstanceMember::clstoptr
static std::enable_if< std::is_pointer< C2_ >::value, const C2_ >::type clstoptr(const C2_ val)
Definition: Embedding.h:886
Gorgon::Scripting::MappedROStaticDataMember
Definition: Embedding.h:1153
Gorgon::Scripting::MappedROStaticDataMember::GetValue
T_ GetValue() const
Returns the value stored in this data.
Definition: Embedding.h:1192
Gorgon::Scripting::MappedROInstanceMember_Function::typecheck
virtual void typecheck(const Type *type) const override
Type checks the parent.
Definition: Embedding.h:1088
Gorgon::Scripting::StaticDataMember::readonly
bool readonly
Marks this instance as read-only.
Definition: Reflection.h:506
Gorgon::Scripting::MappedEventType::MappedEventType
MappedEventType(const std::string &name, const std::string &help, const ParameterList &parameters={}, const Type *parenttype=nullptr, const Type *ret=nullptr)
Definition: Embedding.h:1705
Gorgon::Scripting::ParameterList
std::vector< Parameter > ParameterList
Definition: Reflection.h:308
Gorgon::Scripting::Function::GetOwner
const Type & GetOwner() const
If this function is a member function, returns the owner object.
Definition: Reflection.h:874
Gorgon::Scripting::MappedEventType
R_: return type, P_: parameters, E_: event object type.
Definition: Embedding.h:1561
Gorgon::Scripting::MappedStringEnum::MappedStringEnum
MappedStringEnum(const std::string &name, const std::string &help, const std::vector< std::pair< std::string, std::string >> &strings, E_ defval=E_(), bool binary=false)
strings parameter should contain, name and help of enum entries.
Definition: Embedding.h:1790
Gorgon::Scripting::MappedStringEnum::compare
virtual bool compare(const Data &l, const Data &r) const
This function should compare two instances of the type.
Definition: Embedding.h:1890
Gorgon::Scripting::StaticDataMember::constant
bool constant
This instance member is a constant.
Definition: Reflection.h:500
Gorgon::Scripting::MappedReferenceType::MappedReferenceType
MappedReferenceType(const std::string &name, const std::string &help)
Definition: Embedding.h:1414
Gorgon::Scripting::MappedEventType::deleteobject
virtual void deleteobject(const Gorgon::Scripting::Data &data) const override
This function should delete the given object.
Definition: Embedding.h:1770
Gorgon::Scripting::MappedROInstanceMember::~MappedROInstanceMember
virtual ~MappedROInstanceMember()
Definition: Embedding.h:912
Gorgon::Scripting::Function::IsMember
bool IsMember() const
Returns if this function is a member function of a type.
Definition: Reflection.h:863
Gorgon::Scripting::VirtualMachine::Get
static VirtualMachine & Get()
Returns the current VM for this thread.
Definition: VirtualMachine.h:109
Gorgon::Scripting::Member::parent
const Member * parent
Definition: Reflection.h:358
Gorgon::Scripting::Type::AddInheritance
void AddInheritance(const Type &type, Inheritance::ConversionFunction from, Inheritance::ConversionFunction to)
Adds an inheritance parent.
Definition: Reflection.cpp:257
Gorgon::Scripting::Type::IsReferenceType
bool IsReferenceType() const
Returns whether this type is a reference type.
Definition: Reflection.h:1327
Gorgon::Scripting::Type::AddConstructors
void AddConstructors(std::initializer_list< Function::Overload * > elements)
Adds the given constructors.
Definition: Reflection.h:1298
Gorgon::Scripting::MappedROInstanceMember_Function::readerfn
Scripting::Function::Overload * readerfn
Definition: Embedding.h:1042
Gorgon::Scripting::MapFunctionToInstanceMember
InstanceMember * MapFunctionToInstanceMember(F_ reader, const std::string &name, const std::string &help, const Type *membertype, const Type *parenttype)
This function will map a const data returning function to a read-only, non-ref, const instance member...
Definition: Embedding.h:1147
Gorgon::TMP::Generate
Generates a sequence from 0 to the given value.
Definition: TMP.h:18
Gorgon::Utils::ASSERT_FALSE
void ASSERT_FALSE(const std::string &message, int skip=1, int depth=4)
Definition: Assert.h:192
Gorgon::Scripting::MappedReferenceType::ToString
virtual std::string ToString(const Data &data) const override
Converts a data of this type to string.
Definition: Embedding.h:1420
Gorgon::Scripting::Data::GetType
const Type & GetType() const
Returns the type of the data.
Definition: Data.h:173
Gorgon::Scripting::MappedFunction
This class wraps a C++ function into an overload. It can be constructed using MapFunction.
Definition: Embedding.h:54
Gorgon::Scripting::MappedROInstanceMember::member
T_ classbase::* member
Definition: Embedding.h:944
Gorgon::Scripting::MappedROInstanceMember
This class allows a one to one mapping of a data member to a c++ data member.
Definition: Embedding.h:844
Gorgon::Scripting::MappedROInstanceMember::getnonref
std::enable_if< std::is_copy_constructible< T2_ >::value, Data >::type getnonref(Data &data) const
Definition: Embedding.h:896
Gorgon::Scripting::MappedEventType::ToString
virtual std::string ToString(const Gorgon::Scripting::Data &) const override
Converts a data of this type to string.
Definition: Embedding.h:1760
Gorgon::Scripting::MappedROInstanceMember::deref
static std::enable_if< istypeptr, typename std::remove_pointer< T2_ >::type >::type deref(const T2_ val)
Definition: Embedding.h:866
Gorgon::Scripting::MappedROInstanceMember_Function::set
virtual void set(Data &source, Data &value) const override
This function should perform set operation.
Definition: Embedding.h:1092
Gorgon::Scripting::MappedOperator
This class makes working with operators easier.
Definition: Embedding.h:635
Gorgon::Scripting::MappedROInstanceMember::toptr
static std::enable_if< istypeptr, T2_ >::type toptr(T2_ val)
Definition: Embedding.h:876
Gorgon::Scripting::MappedROInstanceMember_Function::fn
Scripting::Function fn
Definition: Embedding.h:1041
Gorgon::Scripting::MappedROInstanceMember::classptr
typename std::remove_pointer< C_ >::type * classptr
Definition: Embedding.h:847
Gorgon::Scripting::MappedOperator::MappedOperator
MappedOperator(const std::string &name, const std::string &help, const Type *parent, std::initializer_list< Function::Overload * > overloads)
Definition: Embedding.h:655
Gorgon::Scripting::MappedInstanceMember_Function::set
virtual void set(Data &source, Data &value) const override
This function should perform set operation.
Definition: Embedding.h:1138
Gorgon::Scripting::Type
This class stores information about types.
Definition: Reflection.h:1165
Gorgon
Root namespace for Gorgon Game Engine.
Definition: Any.h:19
Gorgon::Scripting::InstanceMember::type
const Type * type
Type of the datamember.
Definition: Reflection.h:1056
Gorgon::TMP::AbstractRTTC
Runtime type class, implements RTTH.
Definition: TMP.h:401
Gorgon::TMP::RTTH::NormalType
RTTS & NormalType
Definition: TMP.h:375
Gorgon::Scripting::MappedReferenceType::Assign
virtual void Assign(Data &l, const Data &r) const override
Definition: Embedding.h:1453
Gorgon::Scripting::Data::GetReference
Data GetReference()
Definition: Data.cpp:148
Gorgon::Scripting::MappedROStaticDataMember::istypeptr
@ istypeptr
Definition: Embedding.h:1159
Gorgon::Scripting::MappedROInstanceMember::clstoptr
static std::enable_if<!std::is_pointer< C2_ >::value, const C2_ * >::type clstoptr(const C2_ &val)
Definition: Embedding.h:891
Gorgon::TMP::RTTH::ConstRefType
RTTS & ConstRefType
Definition: TMP.h:375
Gorgon::Scripting::Data::IsReference
bool IsReference() const
Returns if this data contains a reference.
Definition: Data.cpp:212
ASSERT
#define ASSERT(expression, message,...)
Replaces regular assert to allow messages and backtrace.
Definition: Assert.h:161
Gorgon::Scripting::MappedFunction::MappedFunction
MappedFunction(F_ fn, const Scripting::Type *returntype, Scripting::ParameterList parameters, P_ ...tags)
Constructor.
Definition: Embedding.h:63
Gorgon::Scripting::Data::Invalid
static Data Invalid()
Constructs an invalid data object.
Definition: Data.h:27
Gorgon::Scripting::MappedROInstanceMember::typecheck
virtual void typecheck(const Scripting::Type *type) const override final
Type checks the parent.
Definition: Embedding.h:915
Gorgon::Scripting::Type::AddMember
virtual void AddMember(StaticMember &member) override
Adds a static member to this type.
Definition: Reflection.h:1214
Gorgon::Scripting::MappedValueType::deleteobject
virtual void deleteobject(const Data &obj) const override
Definition: Embedding.h:1354
Gorgon::Scripting::MappedReferenceType::MappedReferenceType
MappedReferenceType(const std::string &name, const std::string &help, T_ *def)
Definition: Embedding.h:1408
Gorgon::Scripting::Function::Overload::parent
Function * parent
The parent function of this variant.
Definition: Reflection.h:763
Gorgon::Scripting::MappedOperator::MappedOperator
MappedOperator(const std::string &name, const std::string &help, const Type *parent, const Type *returntype, const Type *rhs, F_ fn)
Constructor, returntype and parent could be nullptr, tags are optional.
Definition: Embedding.h:639
Gorgon::Scripting::MappedValueType::addcopyconst
std::enable_if<!std::is_copy_constructible< O_ >::value, void >::type addcopyconst()
Definition: Embedding.h:1392
Gorgon::Scripting::MappedROStaticDataMember::getnonref
std::enable_if< std::is_copy_constructible< T2_ >::value, Data >::type getnonref()
Definition: Embedding.h:1170
Gorgon::Scripting::OptionList
std::vector< Any > OptionList
Definition: Reflection.h:114
Gorgon::Scripting::MappedROStaticDataMember::set
virtual void set(Data &source, Data &value) const override
Definition: Embedding.h:1231
Gorgon::Scripting::MappedROInstanceMember::istypeptr
@ istypeptr
Definition: Embedding.h:852
Gorgon::Scripting::MappedFunction::Call
virtual Data Call(bool ismethod, const std::vector< Data > &parameters) const override
Class the stub for this function.
Definition: Embedding.h:67
Gorgon::Scripting::ReferenceTag
@ ReferenceTag
Marks the object as a reference.
Definition: Reflection.h:61
Gorgon::Scripting::MappedValueType::Assign
virtual void Assign(Data &l, const Data &r) const override
Definition: Embedding.h:1336
Gorgon::Scripting::MapDynamicInheritance
void MapDynamicInheritance(Type *type, Type *inherited)
Definition: Embedding.h:1912
VirtualMachine.h
Gorgon::Scripting::MappedROInstanceMember::istypeconst
@ istypeconst
Definition: Embedding.h:851
Gorgon::Scripting::Data::SetParent
void SetParent(const Data data)
Definition: Data.h:141
Gorgon::Scripting::ParseFn
T_(*)(const std::string &) ParseFn
Definition: Embedding.h:27
Gorgon::Scripting::ParseThrow
T_ ParseThrow(const std::string &)
Definition: Embedding.h:35
Gorgon::Scripting::MappedStaticDataMember
Definition: Embedding.h:1238
Gorgon::Scripting::Function::Overload
Represents a function overload.
Definition: Reflection.h:588
Gorgon::Scripting::MappedReferenceType::addcopyconst
std::enable_if< std::is_copy_constructible< O_ >::value, void >::type addcopyconst()
Definition: Embedding.h:1473
Gorgon::Scripting::MapOperator
Scripting::Function::Overload * MapOperator(F_ fn, const Type *returntype, const Type *rhs)
Definition: Embedding.h:626
Gorgon::Scripting::Function::Overload::repeatlast
bool repeatlast
If true last parameter can be specified any number of times.
Definition: Reflection.h:747
Gorgon::Scripting::ConstTag
@ ConstTag
Marks a parameter or a function constant.
Definition: Reflection.h:95
Gorgon::Scripting::Function::Overload::parameters
ParameterList parameters
Modifiable parameters of this overload.
Definition: Reflection.h:736
Gorgon::Scripting::MappedROInstanceMember_Function::get
virtual Data get(Scripting::Data &data) const override
This function should return the value of this member.
Definition: Embedding.h:1095
Gorgon::Scripting::MappedInstanceMember
This class allows a one to one mapping of a data member to a c++ data member.
Definition: Embedding.h:951
Gorgon::Scripting::MappedValueType
This class allows embedded types to become scripting types that are passed around as values.
Definition: Embedding.h:1300
Gorgon::Scripting::MappedROInstanceMember::get
virtual Data get(Scripting::Data &data) const override
This function should return the value of this member.
Definition: Embedding.h:924
Gorgon::Scripting::MappedStringEnum
E_ is an enumeration with defined strings.
Definition: Embedding.h:1786
Gorgon::Scripting::MappedInstanceMember::getref
std::enable_if<!std::is_pointer< T2_ >::value, T2_ >::type & getref(T2_ &value) const
Definition: Embedding.h:975
Gorgon::Scripting::MappedStaticDataMember::getref
std::enable_if< std::is_pointer< T2_ >::value, typename std::remove_pointer< T2_ >::type >::type & getref()
Definition: Embedding.h:1257
Gorgon::Scripting::MappedROInstanceMember_Function::MappedROInstanceMember_Function
MappedROInstanceMember_Function(F_ reader, const std::string &name, const std::string &help, const Type *type, const Type *parent, bool isconstfn, bool isreffn, bool constant, bool ref, bool readonly)
Definition: Embedding.h:1046
Gorgon::Scripting::MappedStaticDataMember::MappedStaticDataMember
MappedStaticDataMember(T_ value, const std::string &name, const std::string &help, const Type *type, bool constant=false, bool ref=false)
If T_ is a non-pointer type or T_ is pointer and ref is set to true, the value would be used as initi...
Definition: Embedding.h:1243
Gorgon::Scripting::MappedROInstanceMember::MappedROInstanceMember
MappedROInstanceMember(T_ classbase::*member, const std::string &name, const std::string &help, const Type *type, bool constant=false)
Constructor.
Definition: Embedding.h:907
Gorgon::Scripting::MappedROStaticDataMember::istypeconst
@ istypeconst
Definition: Embedding.h:1158
Gorgon::Scripting::Function::Overload::returnsref
bool returnsref
This function variant returns a reference.
Definition: Reflection.h:757
Gorgon::TMP::RTTI::Name
std::string Name() const
Returns human readable name of the type.
Definition: TMP.h:184
Gorgon::Scripting::Parameter
This class represents a function parameter description.
Definition: Reflection.h:137
Gorgon::Scripting::StaticDataMember::GetType
const Type & GetType() const
Returns the type of this static member.
Definition: Reflection.h:464
Gorgon::Scripting::MappedReferenceType::Parse
virtual Data Parse(const std::string &str) const override
Parses a string into this data. This function is allowed to throw.
Definition: Embedding.h:1449
Gorgon::Scripting::InstanceMember::readonly
bool readonly
Marks this instance as read-only.
Definition: Reflection.h:1065
Gorgon::TMP::RTTH::ConstType
RTTS & ConstType
Definition: TMP.h:375
Gorgon::Scripting::InstanceMember::reference
bool reference
This instance member is a reference.
Definition: Reflection.h:1062
Gorgon::Scripting::EnumType
Represents an enumeration type.
Definition: Reflection.h:1540
Gorgon::Scripting::Member::name
std::string name
The name of the datamember.
Definition: Reflection.h:353
Gorgon::GL::UBOBindingPoint::Type
Type
Definition: Shader.h:14
Gorgon::Scripting::MapConstStaticcast
Scripting::Function::Overload * MapConstStaticcast(Type *from, Type *to, bool implicit=true)
Maps a constructor for type casting, works for const reference types.
Definition: Embedding.h:815
Gorgon::Scripting::MappedValueType::Parse
virtual Data Parse(const std::string &str) const override
Parses a string into this data. This function is allowed to throw.
Definition: Embedding.h:1332
Gorgon::Scripting::MappedROInstanceMember::MappedROInstanceMember
MappedROInstanceMember(T_ classbase::*member, const std::string &name, const std::string &help, const Type *type, bool constant, bool ref, bool readonly)
Definition: Embedding.h:855
Gorgon::Scripting::Member::help
std::string help
Help string of the datamember.
Definition: Reflection.h:356
Gorgon::Scripting::MappedReferenceType
This class allows embedded types to become scripting types that are passed around as references.
Definition: Embedding.h:1406
Gorgon::Scripting::MappedROStaticDataMember::get
virtual Data get() const override
This function should return the data. It is overloaded to enforce modifiers.
Definition: Embedding.h:1203
Gorgon::Scripting::MappedROStaticDataMember::normaltype
typename std::remove_const< typename std::remove_pointer< T_ >::type >::type normaltype
Definition: Embedding.h:1155
Gorgon::Scripting::MappedStaticDataMember::getref
std::enable_if<!std::is_pointer< T2_ >::value, T2_ >::type & getref()
Definition: Embedding.h:1262
Gorgon::Scripting::MappedInstanceMember_Function::MappedInstanceMember_Function
MappedInstanceMember_Function(F1_ reader, F2_ writer, const std::string &name, const std::string &help, const Type *type, const Type *parent, bool isconstfn, bool isreffn, bool ref, bool isgetconst, bool issetconst=false)
Constructs a new MappedInstanceMember_Function.
Definition: Embedding.h:1125
Gorgon::Scripting
This namespace contains Gorgon Script parser and reflection facilities.
Definition: Scripting.h:21
Gorgon::Scripting::Data::IsConstant
bool IsConstant() const
Returns if this data is constant.
Definition: Data.h:160
Gorgon::Scripting::MappedROInstanceMember::set
virtual void set(Data &source, Data &value) const override
This function should perform set operation.
Definition: Embedding.h:921
Gorgon::Scripting::MapFunction
Scripting::Function::Overload * MapFunction(F_ fn, const Type *returntype, ParameterList parameters, P_ ...tags)
Definition: Embedding.h:614
Gorgon::Scripting::InstanceMember::constant
bool constant
This instance member is a constant.
Definition: Reflection.h:1059
Gorgon::Scripting::MappedStringEnum::ToString
virtual std::string ToString(const Data &d) const
Converts a data of this type to string.
Definition: Embedding.h:1864
Gorgon::TMP::RTTI::IsSameType
virtual bool IsSameType(const std::type_info &) const =0
Compares the type stored with this service to the given type info.
Exceptions.h
Exceptions This file contains string related exceptions.
Gorgon::Scripting::MappedROInstanceMember::getnonref
std::enable_if<!std::is_copy_constructible< T2_ >::value, Data >::type getnonref(Data &data) const
Definition: Embedding.h:901
Gorgon::Scripting::Function::Overload::returnsconst
bool returnsconst
This function variant returns a constant, useful with references.
Definition: Reflection.h:760
Gorgon::Scripting::MappedStringEnum::Assign
virtual void Assign(Data &l, const Data &r) const override
Assigns the value of the second parameter to the first, reference types can ignore this function.
Definition: Embedding.h:1872
Gorgon::Scripting::MappedStringEnum::Parse
virtual Data Parse(const std::string &s) const
Parses a string into this data. This function is allowed to throw.
Definition: Embedding.h:1868
Gorgon::TMP::RTTH::PtrType
RTTS & PtrType
Definition: TMP.h:375
Gorgon::Scripting::MappedInstanceMember::MappedInstanceMember
MappedInstanceMember(T_ classbase::*member, const std::string &name, const std::string &help, const Type *type, bool constant=false, bool ref=false)
Constructor.
Definition: Embedding.h:955
Gorgon::Scripting::Types::Function
const Scripting::Type & Function()
Definition: Reflection.h:589
Gorgon::Scripting::Function
Represents a function.
Definition: Reflection.h:557
MAP_COMPARE
#define MAP_COMPARE(opname, op, mappedtype, cpptype)
Creates a comparison function.
Definition: Embedding.h:692
Gorgon::Scripting::MappedValueType::ToString
virtual std::string ToString(const Data &data) const override
Converts a data of this type to string.
Definition: Embedding.h:1327
Gorgon::Scripting::VirtualMachine::GetOutput
std::ostream & GetOutput() const
Returns the output stream.
Definition: VirtualMachine.h:145
Gorgon::Scripting::MappedROInstanceMember_Function
This class allows mapping of a data member to c++ function data member.
Definition: Embedding.h:1039
Gorgon::Scripting::MapTypecast
Scripting::Function::Overload * MapTypecast(Type *from, Type *to, bool implicit=true)
Maps a constructor for type casting, works for value types.
Definition: Embedding.h:702
Gorgon::Scripting::MappedStringEnum::MappedStringEnum
MappedStringEnum(const std::string &name, const std::string &help, E_ defval=E_(), bool binary=false)
This constructor adds all elements without any help.
Definition: Embedding.h:1857
Gorgon::Scripting::StaticMember::EventType
@ EventType
An event type, which contains additional information about an event.
Definition: Reflection.h:373
Gorgon::Scripting::MappedROInstanceMember::classbase
typename std::remove_pointer< C_ >::type classbase
Definition: Embedding.h:848
Gorgon::Scripting::StringFromFn
std::string(*)(const T_ &) StringFromFn
Definition: Embedding.h:24
Gorgon::Scripting::InstanceMember
This class represents an instance data member.
Definition: Reflection.h:989
Gorgon::Scripting::ToEmptyString
std::string ToEmptyString(const T_ &)
Definition: Embedding.h:30
Gorgon::Scripting::MappedValueType::MappedValueType
MappedValueType(const std::string &name, const std::string &help, const T_ &def)
Definition: Embedding.h:1302
Gorgon::Scripting::ImplicitTag
@ ImplicitTag
Makes a constructor implicit.
Definition: Reflection.h:105
Gorgon::Scripting::StaticDataMember::type
const Type * type
Type of the datamember.
Definition: Reflection.h:497
Gorgon::Scripting::VirtualMachine::ExecuteFunction
Data ExecuteFunction(const Function *fn, const std::vector< Data > &params, bool method)
Executes a function in the current scope.
Definition: VirtualMachine.cpp:1421
Gorgon::Scripting::MappedROStaticDataMember::MappedROStaticDataMember
MappedROStaticDataMember(T_ value, const std::string &name, const std::string &help, const Type *type, bool isconstant=false)
If T_ is not a pointer, uses the value as initial value and stores the current value locally.
Definition: Embedding.h:1183
Gorgon::Scripting::MappedROStaticDataMember::getnonref
std::enable_if<!std::is_copy_constructible< T2_ >::value, Data >::type getnonref()
Definition: Embedding.h:1175
Gorgon::Scripting::Function::IsStatic
bool IsStatic() const
Returns if this function is static. Only meaningful when the function is a member function.
Definition: Reflection.h:858
Gorgon::Scripting::EventType
Events allow an easy mechanism to program logic into actions instead of checking actions continuously...
Definition: Reflection.h:1491
Gorgon::Scripting::MapConstDynamiccast
Scripting::Function::Overload * MapConstDynamiccast(Type *from, Type *to, bool implicit=true)
Maps a constructor for type casting, works for polymorphic types.
Definition: Embedding.h:759
Gorgon::Scripting::StaticDataMember
Definition: Reflection.h:421
Gorgon::Scripting::Member::GetName
std::string GetName() const
Returns the name of this member.
Definition: Reflection.h:325
Gorgon::Scripting::MappedEventType::Parse
virtual Data Parse(const std::string &) const override
Parses a string into this data. This function is allowed to throw.
Definition: Embedding.h:1764