Changeset 237

Show
Ignore:
Timestamp:
11/17/07 00:24:58 (1 year ago)
Author:
JarrettBillingsley
Message:

--

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/minid/bind.d

    r236 r237  
    4646            { 
    4747                dchar[] name = utf.toUtf32(member.Name); 
    48                 ns[name] = MDValue(new MDClosure(ns, &member.Function, name)); 
     48                ns[name] = MDValue(new MDClosure(ns, &member.WrappedFunc, name)); 
    4949            } 
    5050            else static if(is(typeof(member.isClass))) 
    5151            { 
    5252                dchar[] name = utf.toUtf32(member.Name); 
    53                 ns[name] = MDValue(new member.Class()); 
     53                ns[name] = MDValue(member.makeClass()); 
    5454            } 
    5555            else static if(is(typeof(member.isStruct))) 
     
    8080This wraps a function, and is meant to be used as a parameter to WrapModule. 
    8181*/ 
    82 public struct WrapFunc(alias func, char[] name = NameOfFunc!(func), funcType = typeof(&func)
     82public struct WrapFunc(alias func
    8383{ 
    8484    const bool isFunc = true; 
    85     alias WrappedFunc!(func, name, funcType) Function
    86     const char[] Name = name
     85    const char[] Name = NameOfFunc!(func)
     86    mixin WrappedFunc!(func, Name, typeof(&func))
    8787} 
    8888 
     
    9090public template WrapFunc(alias func, funcType) 
    9191{ 
    92     alias WrapFunc!(func, NameOfFunc!(func), funcType) WrapFunc; 
     92    const bool isFunc = true; 
     93    const char[] Name = NameOfFunc!(func); 
     94    mixin WrappedFunc!(func, Name, funcType); 
     95
     96 
     97/// ditto 
     98public struct WrapFunc(alias func, char[] name) 
     99
     100    const bool isFunc = true; 
     101    const char[] Name = name; 
     102    mixin WrappedFunc!(func, Name, typeof(&func)); 
     103
     104 
     105/// ditto 
     106public struct WrapFunc(alias func, char[] name, funcType) 
     107
     108    const bool isFunc = true; 
     109    const char[] Name = name; 
     110    mixin WrappedFunc!(func, Name, funcType); 
    93111} 
    94112 
     
    116134} 
    117135 
     136private class WrappedClass : MDClass 
     137{ 
     138    private this(dchar[] name, MDClass base) 
     139    { 
     140        super(name, base); 
     141    } 
     142 
     143    public override WrappedInstance newInstance() 
     144    { 
     145        return new WrappedInstance(this); 
     146    } 
     147} 
     148 
    118149private class WrappedInstance : MDInstance 
    119150{ 
     
    128159private class WrappedStruct(T) : MDInstance 
    129160{ 
    130 //  alias FieldNames!(T) fieldNames; 
    131161    private T inst; 
    132162 
     
    135165        super(owner); 
    136166    } 
    137  
    138 //  private void updateFields() 
    139 //  { 
    140 //      foreach(i, v; fieldNames) 
    141 //          mFields[mixin("\"" ~ fieldNames[i] ~ "\"d")] = MDValue(inst.tupleof[i]); 
    142 //  } 
    143 //  
    144 //  private T* toStruct() 
    145 //  { 
    146 //      foreach(i, v; fieldNames) 
    147 //          inst.tupleof[i] = mFields[mixin("\"" ~ fieldNames[i] ~ "\"d")].to!(typeof(inst.tupleof[i])); 
    148 //  
    149 //      return &inst; 
    150 //  } 
    151167} 
    152168 
    153169/** 
    154170Wraps a D class of the given type with the given members.  name is the name that will be given to the class in MiniD. 
     171This is meant to be used as a parameter to WrapModule. 
    155172*/ 
    156173public struct WrapClass(ClassType, char[] name = ClassType.stringof, Members...) 
     
    161178    const char[] Name = name; 
    162179    const CtorCount = CountCtors!(Members); 
     180    const className = ToUTF32!(name); 
    163181 
    164182    static assert(CtorCount <= 1, "Cannot have more than one WrapCtors instance in wrapped class parameters for class " ~ ClassType.stringof); 
    165183 
    166     static class Class : MDClass 
    167     { 
    168         private this() 
    169         { 
    170             alias BaseTypeTupleOf!(ClassType) Bases; 
     184    public static WrappedClass makeClass() 
     185    { 
     186        alias BaseTypeTupleOf!(ClassType) Bases; 
     187 
     188        if(typeid(ClassType) in WrappedClasses) 
     189            throw new MDException("Native class " ~ ClassType.stringof ~ " cannot be wrapped more than once"); 
     190 
     191        WrappedClass self; 
     192 
     193        static if(!is(Bases[0] == Object)) 
     194        { 
     195            self = new WrappedClass(className, GetWrappedClass(typeid(Bases[0]))); 
     196        } 
     197        else 
     198        { 
     199            self = new WrappedClass(className, null); 
     200        } 
     201         
     202        WrappedClasses[typeid(ClassType)] = self; 
     203 
     204        foreach(i, member; Members) 
     205        { 
     206            static if(is(typeof(member.isMethod))) 
     207            { 
     208                const name = ToUTF32!(member.Name); 
     209                self.mMethods[name] = MDValue(new MDClosure(self.mMethods, &WrappedMethod!(member.Func, member.FuncType, ClassType), className ~ "." ~ name)); 
     210            } 
     211            else static if(is(typeof(member.isProperty))) 
     212            { 
     213                const name = ToUTF32!(member.Name); 
     214                self.mMethods[name] = MDValue(new MDClosure(self.mMethods, &WrappedProperty!(member.Func, member.Name, member.FuncType, ClassType), className ~ "." ~ name)); 
     215            } 
     216            else static if(is(typeof(member.isCtors))) 
     217            { 
     218                self.mMethods["constructor"d] = MDValue(new MDClosure(self.mMethods, &constructor!(member.Types), className ~ ".constructor")); 
     219            } 
     220            else 
     221                static assert(false, "Invalid member type '" ~ typeof(member).stringof ~ "' in wrapped class '" ~ name ~ "'"); 
     222        } 
     223 
     224        static if(CtorCount == 0) 
     225            self.mMethods["constructor"d] = MDValue(new MDClosure(self.mMethods, &defaultCtor, className ~ ".constructor")); 
    171226             
    172             if(typeid(ClassType) in WrappedClasses) 
    173                 throw new MDException("Native class " ~ ClassType.stringof ~ " cannot be wrapped more than once"); 
    174              
    175             WrappedClasses[typeid(ClassType)] = this; 
    176             dchar[] className = utf.toUtf32(name); 
    177  
    178             static if(!is(Bases[0] == Object)) 
    179             { 
    180                 super(className, GetWrappedClass(typeid(Bases[0]))); 
    181             } 
    182             else 
    183             { 
    184                 super(className, null); 
    185             } 
    186  
    187             foreach(i, member; Members) 
    188             { 
    189                 static if(is(typeof(member.isMethod))) 
    190                 { 
    191                     dchar[] name = utf.toUtf32(member.Name); 
    192                     mMethods[name] = MDValue(new MDClosure(mMethods, &WrappedMethod!(member.Func, member.FuncType, ClassType), className ~ "." ~ name)); 
    193                 } 
    194                 else static if(is(typeof(member.isProperty))) 
    195                 { 
    196                     dchar[] name = utf.toUtf32(member.Name); 
    197                     mMethods[name] = MDValue(new MDClosure(mMethods, &WrappedProperty!(member.Func, member.Name, member.FuncType, ClassType), className ~ "." ~ name)); 
    198                 } 
    199                 else static if(is(typeof(member.isCtors))) 
    200                 { 
    201                     mMethods["constructor"d] = MDValue(new MDClosure(mMethods, &constructor!(member.Types), className ~ ".constructor")); 
    202                 } 
    203                 else 
    204                     static assert(false, "Invalid member type '" ~ typeof(member).stringof ~ "' in wrapped class '" ~ name ~ "'"); 
    205             } 
    206  
    207             static if(CtorCount == 0) 
    208                 mMethods["constructor"d] = MDValue(new MDClosure(mMethods, &defaultCtor, className ~ ".constructor")); 
    209         } 
    210  
    211         public override WrappedInstance newInstance() 
    212         { 
    213             return new WrappedInstance(this); 
    214         } 
    215  
    216         static if(CtorCount == 0) 
    217         { 
    218             static assert(is(typeof(new ClassType())), "Cannot call default constructor for class " ~ ClassType.stringof ~ "; please wrap a constructor explicitly"); 
    219  
    220             private int defaultCtor(MDState s, uint numParams) 
    221             { 
    222                 auto self = s.getContext!(WrappedInstance); 
    223                 assert(self !is null, "Invalid 'this' parameter passed to " ~ ClassType.stringof ~ ".constructor"); 
    224  
    225                 self.inst = new ClassType(); 
    226                 return 0; 
    227             } 
    228         } 
    229  
    230         private int constructor(Ctors...)(MDState s, uint numParams) 
     227        return self; 
     228    } 
     229 
     230    static if(CtorCount == 0) 
     231    { 
     232        static assert(is(typeof(new ClassType())), "Cannot call default constructor for class " ~ ClassType.stringof ~ "; please wrap a constructor explicitly"); 
     233 
     234        private static int defaultCtor(MDState s, uint numParams) 
     235        { 
     236            auto self = s.getContext!(WrappedInstance); 
     237            assert(self !is null, "Invalid 'this' parameter passed to " ~ ClassType.stringof ~ ".constructor"); 
     238 
     239            self.inst = new ClassType(); 
     240            return 0; 
     241        } 
     242    } 
     243    else 
     244    { 
     245        private static int constructor(Ctors...)(MDState s, uint numParams) 
    231246        { 
    232247            auto self = s.getContext!(WrappedInstance); 
     
    256271                } 
    257272            } 
    258             
     273     
    259274            for(uint i = 0; i < numParams; i++) 
    260275                args[i] = s.getParam(i); 
     
    268283            { 
    269284                typeString ~= s.getParam(0u).typeString(); 
    270             
     285     
    271286                for(uint i = 1; i < numParams; i++) 
    272287                    typeString ~= ", " ~ s.getParam(i).typeString(); 
    273288            } 
    274             
     289     
    275290            typeString ~= ")"; 
    276291 
     
    387402Wrap a class method given an alias to the method (like A.foo).  To be used as a parameter to one of the class wrapping templates. 
    388403*/ 
    389 public struct WrapMethod(alias func, char[] name = NameOfFunc!(func), funcType = typeof(&func)
     404public struct WrapMethod(alias func
    390405{ 
    391406    const bool isMethod = true; 
     407    const char[] Name = NameOfFunc!(func); 
    392408    alias func Func; 
     409    alias typeof(&func) FuncType; 
     410} 
     411 
     412/// ditto 
     413public struct WrapMethod(alias func, char[] name) 
     414{ 
     415    const bool isMethod = true; 
    393416    const char[] Name = name; 
     417    alias func Func; 
     418    alias typeof(&func) FuncType; 
     419} 
     420 
     421/// ditto 
     422public struct WrapMethod(alias func, funcType) 
     423{ 
     424    const bool isMethod = true; 
     425    const char[] Name = NameOfFunc!(func); 
     426    alias func Func; 
    394427    alias funcType FuncType; 
    395428} 
    396429 
    397430/// ditto 
    398 public template WrapMethod(alias func, funcType) 
    399 
    400     alias WrapMethod!(func, NameOfFunc!(func), funcType) WrapMethod; 
     431public struct WrapMethod(alias func, char[] name, funcType) 
     432
     433    const bool isMethod = true; 
     434    const char[] Name = name; 
     435    alias func Func; 
     436    alias funcType FuncType; 
    401437} 
    402438 
     
    408444or getter as appropriate based on how many parameters were passed to the MiniD method. 
    409445*/ 
    410 public struct WrapProperty(alias func, char[] name = NameOfFunc!(func), funcType = typeof(&func)) 
     446public struct WrapProperty(alias func) 
     447
     448    const bool isProperty = true; 
     449    alias func Func; 
     450    const char[] Name = NameOfFunc!(func); 
     451    alias typeof(&func) FuncType; 
     452
     453 
     454/// ditto 
     455public struct WrapProperty(alias func, char[] name) 
     456
     457    const bool isProperty = true; 
     458    alias func Func; 
     459    const char[] Name = name; 
     460    alias typeof(&func) FuncType; 
     461
     462 
     463/// ditto 
     464public struct WrapProperty(alias func, funcType) 
     465
     466    const bool isProperty = true; 
     467    alias func Func; 
     468    const char[] Name = NameOfFunc!(func); 
     469    alias funcType FuncType; 
     470
     471 
     472/// ditto 
     473public struct WrapProperty(alias func, char[] name, funcType) 
    411474{ 
    412475    const bool isProperty = true; 
     
    441504    static class Class : MDClass 
    442505    { 
    443         private this() 
     506        public this() 
    444507        { 
    445508            if(typeid(StructType) in WrappedClasses) 
     
    447510 
    448511            WrappedClasses[typeid(StructType)] = this; 
    449             dchar[] structName = utf.toUtf32(name); 
    450              
     512            const structName = ToUTF32!(name); 
     513 
    451514            super(structName, null); 
    452  
    453             //foreach(i, n; FieldNames!(StructType)) 
    454             //  mFields[mixin("\"" ~ FieldNames!(StructType)[i] ~ "\"d")] = MDValue(StructType.init.tupleof[i]); 
    455515 
    456516            mMethods["opIndex"d] = MDValue(new MDClosure(mMethods, &getField, structName ~ ".opIndex")); 
     
    526586                } 
    527587            } 
    528              
     588 
    529589            for(uint i = 0; i < numParams; i++) 
    530590                args[i] = s.getParam(i); 
     
    542602                    typeString ~= ", " ~ s.getParam(i).typeString(); 
    543603            } 
    544              
     604 
    545605            typeString ~= ")"; 
    546606 
    547607            s.throwRuntimeException("Parameter list {} passed to constructor does not match any wrapped constructors", typeString); 
    548608        } 
    549          
     609 
    550610        private int getField(MDState s, uint numParams) 
    551611        { 
     
    656716} 
    657717 
    658 private int WrappedFunc(alias func, char[] name, funcType)(MDState s, uint numParams) 
    659 
    660     ParameterTupleOf!(funcType) args; 
    661     const minArgs = MinArgs!(func); 
    662     const maxArgs = args.length; 
    663  
    664     if(numParams < minArgs) 
    665         s.throwRuntimeException("At least " ~ itoa!(minArgs) ~ " parameter" ~ (minArgs == 1 ? "" : "s") ~ " expected, not {}", numParams); 
    666  
    667     if(numParams > maxArgs) 
    668         numParams = maxArgs; 
    669  
    670     static if(args.length == 0) 
    671     { 
    672         static if(is(ReturnTypeOf!(funcType) == void)) 
    673         { 
    674             func(); 
    675             return 0; 
     718private template WrappedFunc(alias func, char[] name, funcType) 
     719
     720    static int WrappedFunc(MDState s, uint numParams) 
     721    { 
     722        ParameterTupleOf!(funcType) args; 
     723        const minArgs = MinArgs!(func); 
     724        const maxArgs = args.length; 
     725     
     726        if(numParams < minArgs) 
     727            s.throwRuntimeException("At least " ~ itoa!(minArgs) ~ " parameter" ~ (minArgs == 1 ? "" : "s") ~ " expected, not {}", numParams); 
     728     
     729        if(numParams > maxArgs) 
     730            numParams = maxArgs; 
     731     
     732        static if(args.length == 0) 
     733        { 
     734            static if(is(ReturnTypeOf!(funcType) == void)) 
     735            { 
     736                func(); 
     737                return 0; 
     738            } 
     739            else 
     740            { 
     741                s.push(ToMiniDType(func())); 
     742                return 1; 
     743            } 
    676744        } 
    677745        else 
    678746        { 
    679             s.push(ToMiniDType(func())); 
    680             return 1; 
    681         } 
    682     } 
    683     else 
    684     { 
    685         static if(minArgs == 0) 
    686         { 
    687             if(numParams == 0) 
    688             { 
    689                 static if(is(ReturnTypeOf!(funcType) == void)) 
    690                 { 
    691                     func(); 
    692                     return 0; 
    693                 } 
    694                 else 
    695                 { 
    696                     s.push(ToMiniDType(func())); 
    697                     return 1; 
    698                 } 
    699             } 
    700         } 
    701  
    702         foreach(i, arg; args) 
    703         { 
    704             const argNum = i + 1; 
    705  
    706             if(i < numParams) 
    707                 args[i] = GetParameter!(typeof(arg))(s, i); 
    708  
    709             static if(argNum >= minArgs && argNum <= maxArgs) 
    710             { 
    711                 if(argNum == numParams) 
     747            static if(minArgs == 0) 
     748            { 
     749                if(numParams == 0) 
    712750                { 
    713751                    static if(is(ReturnTypeOf!(funcType) == void)) 
    714752                    { 
    715                         func(args[0 .. argNum]); 
     753                        func(); 
    716754                        return 0; 
    717755                    } 
    718756                    else 
    719757                    { 
    720                         s.push(ToMiniDType(func(args[0 .. argNum]))); 
     758                        s.push(ToMiniDType(func())); 
    721759                        return 1; 
    722760                    } 
    723761                } 
    724762            } 
    725         } 
    726     } 
    727  
    728     assert(false, "WrappedFunc should never ever get here."); 
     763     
     764            foreach(i, arg; args) 
     765            { 
     766                const argNum = i + 1; 
     767     
     768                if(i < numParams) 
     769                    args[i] = GetParameter!(typeof(arg))(s, i); 
     770     
     771                static if(argNum >= minArgs && argNum <= maxArgs) 
     772                { 
     773                    if(argNum == numParams) 
     774                    { 
     775                        static if(is(ReturnTypeOf!(funcType) == void)) 
     776                        { 
     777                            func(args[0 .. argNum]); 
     778                            return 0; 
     779                        } 
     780                        else 
     781                        { 
     782                            s.push(ToMiniDType(func(args[0 .. argNum]))); 
     783                            return 1; 
     784                        } 
     785                    } 
     786                } 
     787            } 
     788        } 
     789 
     790        assert(false, "WrappedFunc should never ever get here."); 
     791    } 
    729792} 
    730793 
     
    906969        if(!v.canCastTo!(WrappedInstance)) 
    907970            return false; 
    908              
     971 
    909972        return (cast(T)v.as!(WrappedInstance).inst) !is null; 
    910973    } 
  • trunk/minid/utils.d

    r225 r237  
    706706        alias QSort_greater!(Pred, List[0], List[2 .. $]) QSort_greater; 
    707707} 
     708 
     709/** 
     710Convert string literals between unicode encodings at compile time.  I swear, this should be 
     711built into the compiler or something. 
     712*/ 
     713public template ToUTF8(char[] s) 
     714{ 
     715    const char[] ToUTF8 = s; 
     716} 
     717 
     718/// ditto 
     719public template ToUTF8(wchar[] s) 
     720{ 
     721    const char[] ToUTF8 = mixin("\"" ~ s ~ "\"c"); 
     722} 
     723 
     724/// ditto 
     725public template ToUTF8(dchar[] s) 
     726{ 
     727    const char[] ToUTF8 = mixin("\"" ~ s ~ "\"c"); 
     728} 
     729 
     730/// ditto 
     731public template ToUTF16(char[] s) 
     732{ 
     733    const wchar[] ToUTF16 = mixin("\"" ~ s ~ "\"w"); 
     734} 
     735 
     736/// ditto 
     737public template ToUTF16(wchar[] s) 
     738{ 
     739    const wchar[] ToUTF16 = s; 
     740} 
     741 
     742/// ditto 
     743public template ToUTF16(dchar[] s) 
     744{ 
     745    const wchar[] ToUTF16 = mixin("\"" ~ s ~ "\"w"); 
     746} 
     747 
     748/// ditto 
     749public template ToUTF32(char[] s) 
     750{ 
     751    const dchar[] ToUTF32 = mixin("\"" ~ s ~ "\"d"); 
     752} 
     753 
     754/// ditto 
     755public template ToUTF32(wchar[] s) 
     756{ 
     757    const dchar[] ToUTF32 = mixin("\"" ~ s ~ "\"d"); 
     758} 
     759 
     760/// ditto 
     761public template ToUTF32(dchar[] s) 
     762{ 
     763    const dchar[] ToUTF32 = s; 
     764} 
  • trunk/samples/simple.md

    r236 r237  
    2323    local origin = Point(0.0, 0.0); 
    2424    local white = Color(255, 255, 255); 
     25    local p1 = Point(100.0, 100.0); 
    2526 
    2627    while(!arc.input.keyDown(key.Quit) && !arc.input.keyDown(key.Esc)) 
     
    3031        arc.time.process(); 
    3132 
    32         col.a = (math.sin(((arc.time.getTime() % 1000) / 500.0) * math.pi) + 1) / 4.0 + 0.5; 
    33  
    3433        local p = arc.input.mousePos(); 
    3534 
    3635        font.draw(p.toString(), p, col); 
    37         font.draw(toString(col.a), origin, white); 
     36        font.draw(toString(p1.distance(p)), origin, white); 
    3837        font.draw(toString(arc.time.fps()), Point(0.0, 16.0), white); 
    3938 
     
    6766    { 
    6867        mX; 
    69      
     68 
    7069        this() 
    7170        { 
     
    7978        } 
    8079    } 
    81      
     80 
    8281    class B : A 
    8382    { 
    8483        mY; 
    85      
     84 
    8685        this() 
    8786        { 
    8887            mY = 10; 
    89      
     88 
    9089            writefln("B ctor"); 
    9190            super(); 
    9291        } 
    9392    } 
    94      
     93 
    9594    class C : B 
    9695    { 
  • trunk/test.d

    r236 r237  
    116116                arc.font.Font, 
    117117                WrapCtors!(void function(char[], int)), 
    118                 WrapMethod!(Font.draw) 
     118                /* WrapMethod!(Font.getWidth!(dchar)), 
     119                WrapMethod!(Font.getWidthLastLine!(dchar)), 
     120                WrapMethod!(Font.getHeight), 
     121                WrapMethod!(Font.getLineSkip), 
     122                WrapMethod!(Font.setLineGap), */ 
     123                WrapMethod!(Font.draw, void function(dchar[], Point, Color))//, 
     124                //WrapMethod!(Font.calculateIndex!(dchar)) 
    119125            ) 
    120126        )(ctx); 
     
    134140                WrapMethod!(Point.minComponent), 
    135141                WrapMethod!(Point.opNeg), 
    136                 // cross, dot 
     142                WrapMethod!(Point.cross), 
     143                WrapMethod!(Point.dot), 
    137144                WrapMethod!(Point.scale), 
    138145                // apply 
     
    140147                WrapMethod!(Point.normalise, "normalize"), 
    141148                WrapMethod!(Point.normaliseCopy, "normalizeCopy"), 
    142                 // angle 
    143149                WrapMethod!(Point.rotate), 
     150                WrapMethod!(Point.rotateCopy), 
    144151                WrapMethod!(Point.abs), 
    145152                WrapMethod!(Point.absCopy), 
    146                 // clamp 
     153                WrapMethod!(Point.clamp), 
    147154                WrapMethod!(Point.randomise, "randomize"), 
    148                 // distance, distanceSquared 
    149                 WrapMethod!(Point.rotateCopy), 
     155                WrapMethod!(Point.distance), 
     156                WrapMethod!(Point.distanceSquared), 
    150157                WrapMethod!(Point.getX), 
    151158                WrapMethod!(Point.getY), 
     
    154161                WrapMethod!(Point.addX), 
    155162                WrapMethod!(Point.addY) 
     163                // above, below, left, right 
    156164            ) 
    157165        )(ctx);