Forum Replies Created
-
AuthorPosts
-
How are you creating the codebox? With the ‘<>’ button?
I’ve thought about this a bit and I reckon the best thing to do is to just allow (explicit) object->void ptr->object casting.
This is basically what I did in mojo3d-physics. There’s some native code in there that casts to/from ptr via object_to_handle and handle_to_object functions.
You have to be careful of course. It’s up to you to keep the underlying object ‘alive’, and if you fail to do so and it gets GC’d you’re toast.
I handle this in mojo3d-physics by setting native user data to monkey2 object only when monkey2 object is added to world, and setting userdata back to 0 when it’s removed, eg:
Monkey12345678910111213141516171819202122232425262728Class World...Method Add( body:RigidBody )_bodies.Add( body )body.btBody.setUserPointer( object_to_handle( body ) )_btworld.addRigidBody( body.btBody,body.CollisionGroup,body.CollisionMask )EndMethod Remove( body:RigidBody )_btworld.removeRigidBody( body.btBody )body.btBody.setUserPointer( Null )_bodies.Remove( body )EndField _bodies:=New Stack<RigidBody>...EndThis way, btBody userdata is only non null if RigidBody is safely being kept alive in the World _bodies stack.
I was in fact thinking of adding a safer GCLock()/GCUnlock() system or similar and may yet still do so, but this is clearly a popular feature request so lets go nuts!
I’ve just pushed a new version of Socket. Bind and Listen now have simpler interfaces:
Monkey123Function Bind:Socket( service:String,flags:SocketFlags=SocketFlags.Passive )Function Listen:Socket( service:String,backlog:int=32,flags:SocketFlags=SocketFlags.Passive )SocketFlags.Passive means the socket can be connected to over a network. If this flag is not set (eg: flags parameter is Null), socket can only be connected too via loopback (ie: from same computer). Well, that’s the theory anyway.
This stuff is a bit different than everyone may be used to because I’m trying to keep things ipv6 friendly.
I’ve tested this with echoserver across a LAN – just change HOST on client to network address of server, and comment out ‘New Fiber( Server)’ on client machine and ‘New Fiber( Client )’ on server!
You can’t curently use std.socket to get the network address of a computer. The problem here is that a computer may have several network addresses, eg: an ipv4 address, an ipv6 address and maybe even more. There’s probably a way around this eg: something like EnumHostAddresses, but for now you’ll need to use some other mechanism to find out the computer’s network address, eg: ipconfig on windows or system prefs->network on macos.
Diagnostic messages will eventually be cleaned up, probably moved to a log system. Don’t worry about them for now.
Nice work, very bleeding edge! Will fix the property type bug ASAP.
I’ve successfully had generic struct instances reflected here (eg: Vec3f, Mat4f etc) but it needs a bit more work and I think a REFLECTION_FILTER equivalent also needs to be added before any of this is truly useful.
Sprites has it though?
Sprites are very special case. They don’t interact with lighting, and are added to a ‘mesh’ in realtime so are also very easy to sort. Transparent surfaces are much harder to deal with.
Use the built-in CString type for extern char* type strings, eg:
Monkey123456789101112#Import “../../sweph/lib/libswe.a”#Import “../../sweph/src/swephexp.h”externfunction swe_set_ephe_path( path:CString )publicfunction Main()swe_set_ephe_path( "blah" )endNo news, a ton of other stuff to do first right now, including looking for some actual paid work!
Just compared monkey2 with c++, and they were indeed producing different results – monkey2 was printing 3.14100003 and c++ was printing 3.141000
However, peeking the actual variable memory showed they are storing the same value, and it’s really just the string conversion that differs. In fact, monkey2 converts to string with 9 decimals places, whereas c++ printf uses 6 by default. So the monkey2 result is actually a more accurate representation of the underlying value than the c++ result.
Prining to 9 decimal places in c++ produces the same output (it should, monkey2 uses same c++ libs!), ie: 3.14100003.
The ‘9 decimal places precision’ used in monkey2 was chosen because it’s apparently the number of decimal places you need to use to be able to convert *any* possible float value to a string and back without losing any data (I don’t know the proof of this myself).
There are many values like this that are not exactly representable as floating point, try 0.1 for example. Converting this to a string in monkey2 will produce 0.100000001 (and in c++ if done to 9 decimal places). If you check the underlying bit pattern of 0.1, it’s $3DCCCCCD (in both monkey2 and c++) which would suggest some kind of recurring value (in binary of course, suggesting some numbers that don’t recur in decimal may recur in binary and therefore be unrepresentable).
In the case of 3.141 and 0.1, converting to 6 decimal places and back would still work, but I assume there are other values you can produce through math that would require 9 decimals places to represent correctly so I’m in no rush to ‘fix’ this by converting at less precision.
Socket.Closed just tell you if the local end of the socket connection has been closed, so will be false until you call Socket.Close(). SocketStream.Eof just calls Socket.Closed.
To tell if the peer socket has been gracefully closed (ie: not crashed), you currently have to test for 0 bytes read or written.
This is the ‘clean’ way to do it, but I think a ‘Connected’ style property here would also be nice. SocketStream can use this for Eof too.
Yes, it’s currently implemented via joystick as this is how SDL does. I think this is a bit ugly though and plan to clean it up, but in the meantime try the joystick banana.
I’ve actually had some success with this and it may yet happen!
The trick is to treat the Variant as a ‘box’ for struct values. The struct value still gets copied when you set or get it, but the Set() and Invoke() methods can directly access the value in the variant/box.
So as long as you keep passing the same variant to decl.Set() etc, you’ll be updating the same struct value.
Just had a look at this, and the big problem is that structs are always passed ‘by value’, which means its impossible to modify them ‘by reference’, eg:
Monkey1234567891011121314Struct CField x:IntEndFunction SetX( c:C,i:Int )c.x=iEndFunction Main()Local c:=New CSetX( c,100 )Print c.x 'alas wont print 100!EndThis fails to SetX because SetX() receives a copy of ‘c’, not a reference to the same ‘c’.
Reflection has a similar problem – when you pass the ‘instance’ object to ‘Set’ or ‘Invoke’, you’re passing a copy of the struct value, so any modifications made by Set or Invoke are being made to a copy that will just be thrown away.
So I’ll keep looking, but right now the answer is no.
Beat me to it! Yes, Kind needs to be documented (supposedly is…). Will add IsPublic, IsProtected, IsPrivate (or equivalent) too.
Monkey1234567891011121314151617181920212223242526272829303132333435#Import "<reflection>"Class CField i:IntEndFunction ToString:String( d:DeclInfo,instance:Variant )Select d.TypeCase Typeof<Int> Return String( Cast<Int>( d.Get( instance ) ) )EndReturn "<error>"EndFunction Main()Local c:=New Cc.i=100Local type:=c.InstanceTypeFor Local d:=Eachin type.GetDecls()Select d.KindCase "Field"Print d.Kind+" "+d.Name+"="+ToString( d,c )EndNextEndWhat do you mean by failing – what error are you getting/
Can you post something buildable/runnable?
Monkey123buffer=New DataBuffer( server.CanReceive+1 )server.ReceiveFrom( Varptr buffer, server.CanReceive, addr )Danger! Use ‘buffer.Data’ to get a pointer to the data within a buffer, NOT ‘Varptr buffer’. Varptr buffer returns the address of the buffer object. The above code will completely destroy the contents of the ‘buffer’ reference.‘Varptr object’ should really be illegal, and is likely to become so one day. -
AuthorPosts