Runtime Concept 的模拟(5)

Runtime Concept 的模拟(5)
简化使用方法!
用链式的单继承解决多继承方法的调用不明确的问题。
支持auto concept和non-auto concept。
支持引用类型concept和值类型concept。
已测试支持的编译器:
VC 7.1 (VC 2003)
VC 8.0 (VC 2005)
VC 9.0 (VC 2008)
GCC 3.4.2
GCC 4.2.3

基本原理:
1. 用类继承的方法生成vtable。
2. 用链式的单继承来组合concept。

缺陷:
1. 成员函数的调用方法不知道是不是符合标准,不过估计移植性没什么问题。
2. static应该改为多线程安全的Singleton。
3. 没考虑异常安全。

另:
1. 关于非虚成员函数指针可以指向虚函数并正常调用的问题:
   i) VC 如果指向的是没有基类的类的虚函数就可以。
   ii) GCC 总是可以调用的。
2. VC6 不支持偏特化,不支持类模板参数的成员类模板。

// main.cpp

//  main.cpp
#include  < stdio.h >
#include 
< vector >
#include 
< string >
#include 
" shape.hpp "
#include 
" concept.hpp "

CONCEPT_MEMBER_FUNCTION(c_set_value, set_value, 
void , ( int  Value), (Value));
CONCEPT_MEMBER_FUNCTION(c_set_value1, set_value1, 
void , ( int  Value), (Value));
CONCEPT_MEMBER_FUNCTION(c_set_value2, set_value2, 
void , ( int  Value), (Value));
CONCEPT_MEMBER_FUNCTION(c_set_value3, set_value3, 
void , ( int  Value), (Value));
CONCEPT_MEMBER_FUNCTION(c_set_value4, set_value4, 
void , ( int  Value), (Value));
CONCEPT_MEMBER_FUNCTION(c_draw, draw, 
void , (monitor device)  const , (device));
CONCEPT_FUNCTION(g_set_value, set_value, 
void , (ObjectType  & t,  int  Value), (t, Value));
CONCEPT_FUNCTION(g_drawShape, drawShape, 
void , ( const  ObjectType  & t, monitor device), (t, device));
typedef concept_list
< g_drawShape, 
                     c_draw,
                     c_set_value, 
                     c_set_value1, 
                     c_set_value2, 
                     c_set_value3, 
                     c_set_value4
>  Shape;

template 
<>   struct  concept_map < Shape, Rectangle >   {} ;

////

typedef auto_concept
< Shape >  auto_Shape;

void  DrawShapes(monitor device, std::vector < auto_Shape >   const &  g)
{
    std::vector
<auto_Shape>::const_iterator b(g.begin()), e(g.end());
    
for(; b != e; ++b)
    
{
        b
->draw(device);
        auto_Shape::drawShape(
*b, device);
    }

}


template 
< class  T >
void  DrawShape(monitor device,  const  T &  t)
{
    
if (0) concept<Shape> tmp = t;         //static non-auto concept
    t.draw(device);
}


int  main( int  argc,  char *  argv[])
{
    auto_Shape 
as = Rectangle();
    
int sizeofShape = sizeof(Shape), sizeofconceptShape = sizeof(auto_Shape);
    
as.draw(stdout);
    
as.set_value(1);
    
as.draw(stdout);
    
as.set_value1(sizeofShape);
    
as.draw(stdout);
    
as.set_value2(sizeofconceptShape);
    
as.draw(stdout);
    
as.set_value3(1);
    
as.draw(stdout);

    std::vector
<auto_Shape> vg;
    vg.push_back(Rectangle());
    vg.push_back(Ellipse());
    vg.push_back(vg[
0]);
    vg.push_back(vg[
2]);
    vg[
2= vg[0];
    vg[
3= vg[1];
    
//vg.push_back(Triangle());            //错误,不符合Shape concept // OK in GCC
    
//vg.push_back(std::string("xxx"));    //错误,不符合Shape concept
    DrawShapes(stdout, vg);

    Rectangle rect;
    Ellipse elli;
    EllipseChild ellichild;
    DrawShape(stdout, rect);
    
//DrawShape(stdout, elli);             //错误,不符合Shape static concept
    
//DrawShape(stdout, ellichild);        //错误,不符合Shape static concept
    ref_concept<Shape> ref_non_auto_Shape = rect;
    ref_non_auto_Shape 
= rect;
    
//ref_non_auto_Shape = elli;           //错误,不符合Shape non-auto concept
    printf("rect.value = %d ", rect.value);
    ref_non_auto_Shape.set_value(
1);
    printf(
"rect.value = %d ", rect.value);
    ref_auto_concept
<c_set_value>(rect).set_value(2);
    ref_auto_concept
<g_set_value> x(rect);
    ref_auto_concept
<g_set_value>::set_value(x, 2);
    printf(
"rect.value = %d ", rect.value);

    
return 0;
}


// shape.hpp
//  shape.hpp
#include  < stdio.h >
typedef FILE
*  monitor;

struct  ShapeBase
{
    
int value;
    ShapeBase() : value(
0{}
    
void set_value(int Value)
    
{
        value 
= Value;
    }

    
void set_value1(int Value)
    
{
        value 
= Value;
    }

    
void set_value2(int Value)
    
{
        value 
= Value;
    }

    
void set_value3(int Value)
    
{
        value 
= Value;
    }

    
void set_value4(int Value)
    
{
        value 
= Value;
    }

}
;

struct  Rectangle :  public  ShapeBase
{
    
void draw(monitor device) const
    
{
        fprintf(device, 
"Rectangle.draw: %d ", value);
    }

    
void draw() const
    
{
        printf(
"Rectangle.draw ?: %d ", value);
    }

}
;

struct  Ellipse
{
    
int value;
    Ellipse() : value(
0{}
    
void set_value(int Value)
    
{
        value 
= Value;
    }

    
void set_value1(int Value)
    
{
        value 
= Value;
    }

    
void set_value2(int Value)
    
{
        value 
= Value;
    }

    
void set_value3(int Value)
    
{
        value 
= Value;
    }

    
void set_value4(int Value)
    
{
        value 
= Value;
    }

    
virtual void draw(monitor device) const
    
{
        fprintf(device, 
"Ellipse.draw: %d ", value);
    }

}
;

struct  EllipseChild :  public  Ellipse
{
    
virtual void draw(monitor device) const
    
{
        fprintf(device, 
"EllipseChild.draw?: %d ", value);
    }

}
;

struct  Triangle :  public  ShapeBase
{
    
virtual void draw(monitor device) const
    
{
        fprintf(device, 
"Triangle.draw virtual: %d ", value);
    }

}
;

void  drawShape( const  Rectangle  & refShape, monitor device)
{
    refShape.draw(device);
}


void  drawShape( const  Ellipse  & refShape, monitor device)
{
    refShape.draw(device);
}


void  drawShape( const  Triangle  & refShape, monitor device)
{
    refShape.draw(device);
}


template 
< class  T >
void  set_value(T  & refShape,  int  Value)
{
    refShape.value 
= Value;
}


// concept.hpp
//  concept.hpp
#ifdef _MSC_VER
#define  MEMFUNCCAST(A)          reinterpret_cast<A>
#else
#define  MEMFUNCCAST(A)
#endif

#define  CONCEPT_FUNCTION(CONCEPTNAME, FNAME, RTYPE, FTYPE, PARA) 
struct  CONCEPTNAME 

    template 
<class BaseFrom = concept_base, bool isvtable = trueclass ObjectType = concept_object> 
    
struct table : public concept_bind_with<typename BaseFrom::Base, typename BaseFrom::DeriveFrom, isvtable, ObjectType>::type 
    

        typedef CONCEPTNAME Base; 
        typedef BaseFrom DeriveFrom; 
        typedef typename get_type
<RTYPE (*)FTYPE>::type function_type; 
        function_type p##FNAME; 
        table() : p##FNAME(
&::FNAME) {} 
    }

    template 
<class BaseFrom, class ObjectType> 
    
struct table<BaseFrom, false, ObjectType> : public concept_bind_with<typename BaseFrom::Base, typename BaseFrom::DeriveFrom, false, ObjectType>::type 
    

        typedef CONCEPTNAME Base; 
        typedef BaseFrom DeriveFrom; 
        
const void* CONCEPTNAME##_index() const {return this;} 
        
static RTYPE FNAME FTYPE 
        

            
return (*t.ptable->p##FNAME)PARA; 
        }
 
    }

}
;

#define  CONCEPT_MEMBER_FUNCTION(CONCEPTNAME, FNAME, RTYPE, FTYPE, PARA) 
struct  CONCEPTNAME 

    template 
<class BaseFrom = concept_base, bool isvtable = trueclass ObjectType = concept_object> 
    
struct table : public concept_bind_with<typename BaseFrom::Base, typename BaseFrom::DeriveFrom, isvtable, ObjectType>::type 
    

        typedef CONCEPTNAME Base; 
        typedef BaseFrom DeriveFrom; 
        typedef typename get_type
<RTYPE (ObjectType::*)FTYPE>::type function_type; 
        function_type p##FNAME; 
        table() : p##FNAME(MEMFUNCCAST(function_type)(
&ObjectType::FNAME)) {} 
    }

    template 
<class BaseFrom, class ObjectType> 
    
struct table<BaseFrom, false, ObjectType> : public concept_bind_with<typename BaseFrom::Base, typename BaseFrom::DeriveFrom, false, ObjectType>::type 
    

        typedef CONCEPTNAME Base; 
        typedef BaseFrom DeriveFrom; 
        
const void* CONCEPTNAME##_index() const {return this;} 
        RTYPE FNAME FTYPE 
        

            typedef typename ObjectType::TableType TableType; 
            typedef typename TableType::conceptType conceptType; 
            typedef concept
<conceptType> concept_Type; 
            ObjectType
* This = reinterpret_cast<ObjectType*>
                reinterpret_cast
<size_t>(this- 
                reinterpret_cast
<size_t>
                    reinterpret_cast
<concept_Type*>(0)->CONCEPTNAME##_index())); 
            
return (This->object_pointer->*This->ptable->p##FNAME)PARA; 
        }
 
    }

}
;

template 
< class  T >   struct  get_type  {typedef T type;} ;

struct  concept_base;
struct  concept_object {} ;
template 
< class  conceptT  =   int class  T  =   int >   struct  concept_map  {int t[2];} ;

template 
< class  conceptT,  class  BaseFrom  =  concept_base,  bool  isvtable  =   true class  ObjectType  =  concept_object >
struct  concept_bind_with
{
    typedef typename conceptT::template table
<BaseFrom, isvtable, ObjectType> type;
}
;

struct  concept_base
{
    typedef concept_base Base;
    typedef concept_base DeriveFrom;
    template 
<class BaseFrom = concept_base, bool isvtable = trueclass ObjectType = concept_object>
    
struct table : public concept_bind_with<typename BaseFrom::Base, typename BaseFrom::DeriveFrom, isvtable, ObjectType>::type
    
{
        typedef concept_base Base;
        typedef BaseFrom DeriveFrom;
    }
;
    template 
<bool isvtable, class ObjectType>
    
struct table<concept_base, isvtable, ObjectType>
    
{
        typedef concept_base Base;
        typedef concept_base DeriveFrom;
    }
;
}
;

template 
< class  C0  =  concept_base,   class  C1  =  concept_base,   class  C2  =  concept_base,   class  C3  =  concept_base,   class  C4  =  concept_base,  
          
class  C5  =  concept_base,   class  C6  =  concept_base,   class  C7  =  concept_base,   class  C8  =  concept_base,   class  C9  =  concept_base,  
          
class  C10  =  concept_base,  class  C11  =  concept_base,  class  C12  =  concept_base,  class  C13  =  concept_base,  class  C14  =  concept_base, 
          
class  C15  =  concept_base,  class  C16  =  concept_base,  class  C17  =  concept_base,  class  C18  =  concept_base,  class  C19  =  concept_base  >
struct  concept_list
{
    template 
<class BaseFrom = concept_base, bool isvtable = trueclass T = concept_object>
    
struct table : public
                 concept_bind_with
< C0,typename concept_bind_with< C1,typename concept_bind_with< C2,typename concept_bind_with< C3,typename concept_bind_with< C4,
        typename concept_bind_with
< C5,typename concept_bind_with< C6,typename concept_bind_with< C7,typename concept_bind_with< C8,typename concept_bind_with< C9,
        typename concept_bind_with
<C10,typename concept_bind_with<C11,typename concept_bind_with<C12,typename concept_bind_with<C13,typename concept_bind_with<C14,
        typename concept_bind_with
<C15,typename concept_bind_with<C16,typename concept_bind_with<C17,typename concept_bind_with<C18,typename concept_bind_with<C19,
        BaseFrom
        
>::type>::type>::type>::type>::type>::type>::type>::type>::type>::type
        
>::type>::type>::type>::type>::type>::type>::type>::type>::type, isvtable, T>::type
    
{
        typedef concept_list Base;
        typedef BaseFrom DeriveFrom;
    }
;
}
;

template 
< class  TableT >
struct  concept_class_base
{
    typedef TableT TableType;

    concept_object 
*object_pointer;
    TableT 
*ptable;

    
operator const concept_object&() const return *object_pointer; }
    
operator concept_object&() return *object_pointer; }
}
;

template 
< class  conceptT,  class  T  =  concept_object >
struct  concept_table :  public  concept_bind_with < conceptT, concept_base,  true , T > ::type
{
    typedef conceptT conceptType;

    typedef T
* (*tcloneT)(const T *p);
    typedef 
void (*tdeleteT)(T *p);
    tcloneT pcloneT;
    tdeleteT pdeleteT;
    concept_table() : 
        pcloneT(reinterpret_cast
<tcloneT>(&concept_table::cloneT)), 
        pdeleteT(reinterpret_cast
<tdeleteT>(&concept_table::deleteT)){}

    
static concept_table* vtable()
    
{
        
static concept_table static_table;
        
return &static_table;
    }

    
static T *cloneT(const T *p)
    
{
        
return new T(*p);
    }

    
static void deleteT(T *p)
    
{
        delete p;
    }

}
;

template 
< class  conceptT >
class  auto_concept;
template 
< class  conceptT >
class  ref_concept;
template 
< class  conceptT >
class  ref_auto_concept;

template 
< class  conceptT,  bool  isauto  =   false bool  isref  =   false >
class  concept : 
    
public  concept_class_base < concept_table < conceptT >   >
    
public  concept_bind_with < conceptT, concept_base,  false , concept_class_base < concept_table < conceptT >   >   > ::type
{
public:
    
using concept_class_base<concept_table<conceptT> >::ptable;
    
using concept_class_base<concept_table<conceptT> >::object_pointer;
    typedef concept_table
<conceptT> TableType;
private:
    
void init_with(concept_object* p, TableType* pTable)
    
{
        ptable 
= pTable;
        
if (isref)
        
{
            object_pointer 
= p;
        }

        
else
        
{
            object_pointer 
= (*ptable->pcloneT)(p);
        }

    }

    concept_object 
*cloneT() const
    
{
        
return (*ptable->pcloneT)(object_pointer);
    }

    
void deleteT()
    
{
        (
*ptable->pdeleteT)(object_pointer);
    }

public:
    template 
<class T>
    concept(
const T& t)
    
{
        
if (0char static_assert[isauto || sizeof(concept_map<>!= sizeof(concept_map<conceptT, T>? 1 : -1];
        typedef concept_table
<conceptT, T> cTable;
        init_with(const_cast
<concept_object *>(reinterpret_cast<const concept_object *>(&t)), 
                  (reinterpret_cast
<TableType*>(cTable::vtable())));
    }


    concept(
const concept& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const concept<conceptT, isauto, !isref>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const concept<conceptT, !isauto, isref>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const concept<conceptT, !isauto, !isref>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const auto_concept<conceptT>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const ref_concept<conceptT>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const ref_auto_concept<conceptT>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }

    
~concept()
    
{
        
if (!isref) deleteT();
    }


    concept
& operator = (const concept& rhs)
    
{
        concept(rhs).swap(
*this);
        
return *this;
    }


    
void swap(concept& rhs)
    
{
        concept_object 
*pointer0 = object_pointer;
        TableType 
*ptable0 = ptable;
        object_pointer 
= rhs.object_pointer;
        ptable 
= rhs.ptable;
        rhs.object_pointer 
= pointer0;
        rhs.ptable 
= ptable0;
    }

}
;

template 
< class  conceptT >
class  auto_concept :  public  concept < conceptT,  true false >
{
public:
    template 
<class T>
    auto_concept(
const T& t) : concept<conceptT, truefalse>(t) {}
}
;

template 
< class  conceptT >
class  ref_concept :  public  concept < conceptT,  false true >
{
public:
    template 
<class T>
    ref_concept(
const T& t) : concept<conceptT, falsetrue>(t) {}
}
;

template 
< class  conceptT >
class  ref_auto_concept :  public  concept < conceptT,  true true >
{
public:
    template 
<class T>
    ref_auto_concept(
const T& t) : concept<conceptT, truetrue>(t) {}
}
;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 对于UE5 Runtime环境下的运行时转换,可以使用多种方法进行绘制线。其中一种常用的方法是使用SplineMeshComponent,通过初始化样条线的点位并挂载网格体来实现。这种方法可以添加丰富的材质。另一种方法是使用CableComponent缆索组件,但需要注意缆索的总长度和分段数有一定的限制。还可以使用UWidgetBlueprintLibrary来实现2D的UI屏幕线的绘制。另外,还可以使用FPrimitiveDrawInterface来实现绘制线,包括使用Primitive组件实现的DrawLine,或者使用ULineBatchComponent绘制线。这种方式只能设置线的材质,而不能更改材质。还可以使用DrawDebugLine的方式绘制线,但需要注意在游戏发布后,debug的内容会被优化掉,而不显示。\[1\] 关于UE5 Runtime环境下的C++实现,可以参考相关文档和教程进行开发。\[1\] 至于runtime transformer ue5的具体问题,根据提供的引用内容,没有找到与此相关的信息。请提供更多详细的问题描述,以便我能够给出更准确的回答。 #### 引用[.reference_title] - *1* [UE5实现Runtime环境下绘制线功能](https://blog.csdn.net/weixin_45782925/article/details/130070240)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [UE4 Android Device Compatibility](https://blog.csdn.net/pizi0475/article/details/49785069)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值