00:00:38  * piscisaureus_quit (Quit: ~ Trillian Astra - www.trillian.im ~)
00:09:52  <indutny_sleeping>creationix: yt?
00:16:47  * piscisaureus_joined
00:16:50  * piscisaureus_quit (Client Quit)
00:31:41  * mmaleckichanged nick to mmalecki[zzz]
01:32:03  <creationix>i am, but putting kids to bed
02:00:00  <creationix>ok, I'm back
02:03:29  <creationix>Trying to figure out the C++ object typecasting problem
02:03:42  <creationix>seems you can't cast a uvTimer instance to a uvHandle instance in C++
02:11:24  <creationix>yeah, looks like vtables are chained
02:51:17  * alejandromgjoined
06:12:47  * alejandromgquit (Quit: leaving)
10:17:57  <indutny_sleeping>creationix: yes
10:18:03  <indutny_sleeping>creationix: dynamic_cast, I told ya before
11:59:28  * indutny_sleepingchanged nick to indutny
13:29:40  * mmalecki[zzz]changed nick to mmalecki
13:52:23  * karterkjoined
13:56:37  <creationix>can't dynamic_cast from a void*
13:57:29  <indutny>creationix: yes you can't
13:57:34  <indutny>you should reinterpret_cast to a real class
13:57:42  <indutny>and then dynamic_cast to some parent class
13:57:59  <creationix>well at that point, I can just use the child-class as-is
13:58:11  <creationix>the problem is I don't know what the child-class it in the first-place
13:58:31  <indutny>hm...
13:58:58  <indutny>you should have one class then
13:59:09  <indutny>with type num
13:59:12  <indutny>s/num/enum
14:06:51  * piscisaureus_joined
14:13:42  <creationix>one class with all the methods?
14:13:45  <creationix>I guess that works
14:14:05  <creationix>just wastes a lot of memory
14:15:34  <indutny>creationix: no memory waste :)
14:15:40  <indutny>creationix: methods are static :)
14:15:47  <indutny>creationix: not per instance
14:16:04  <indutny>creationix: only `type` property will waste a 4/8 bytes of memory
14:16:21  <creationix>what about all the callbacks
14:16:26  <creationix>and the uv structs
14:16:35  <creationix>I guess I can union the uv structs
14:16:48  <creationix>but the callbacks kinda need to be unique
14:17:17  * karterkquit (Remote host closed the connection)
14:17:27  <indutny>creationix: yes, you can union them
14:17:29  <indutny>or use pointer
14:18:06  <indutny> /cc piscisaureus_
14:18:16  <indutny>piscisaureus_: how would one organize that stuff with uv?
14:19:00  <indutny>creationix: btw, why not have separate 'close' and other methods?
14:19:07  <indutny>separate for each handle type
14:20:03  <indutny>brb
14:20:08  <indutny>going to take a shower
14:20:18  <creationix>ok, I'm going to eat breakfast
14:37:01  <indutny>creationix: back
14:43:04  <piscisaureus_>indutny: I don't really understand the problem
14:53:34  <indutny>piscisaureus_: one sec
14:53:38  <indutny>creationix: yt?
14:53:45  <creationix>back
14:54:03  <indutny>cool
14:54:45  <creationix>piscisaureus_, I'm trying to find a way to wrap uv_*_t values in candor
14:54:49  <creationix>just the struct is easy
14:55:05  <creationix>I just use timer = CData::New(sizeof(uv_timer_t))
14:55:11  <creationix>well, with the typecast
14:55:24  <creationix>and it will free the memory when the CData value is GCed
14:55:35  <creationix>but I want to store callbacks with the CData too
14:55:45  <creationix>and have a class with methods and not just a struct
14:56:02  <creationix>it all works fine till inheritance gets mixed in
14:56:34  <creationix>here is the base class that wraps uv_handle_t https://github.com/creationix/candor.io/blob/master/src/luv_handle.h
14:57:15  <creationix>I have static C functions that route calls to the instance
14:57:18  <creationix>https://github.com/creationix/candor.io/blob/master/src/luv_handle.cc#L23
14:57:25  <creationix>and https://github.com/creationix/candor.io/blob/master/src/luv_handle.cc#L38
14:57:51  <creationix>the problem is I typecast the void* in both cases to uvHandle instances
14:57:59  <creationix>but they are actually uvTimer instances
14:58:06  <creationix>and C++ classes don't seem to like typecasting that way
14:59:02  <creationix>if I could use instance methods as C callback pointers then that would solve the callback side
14:59:30  <creationix>I could point right to this->OnClose
14:59:40  <creationix>but I don't think function pointers can embed the this pointer like that
15:05:44  * karterkjoined
15:25:38  <creationix>indutny, anyway, about the language, how is progress going?
15:26:17  <piscisaureus_>creationix: looking at it
15:26:35  <indutny>creationix: I think we're close to some sort of 'stable' base
15:26:43  <creationix>assuming we fix my C++ issues, the candor side of the API in really ugly
15:27:04  <indutny>creationix: fixing gc issue atm
15:27:08  <creationix>ok
15:57:02  <piscisaureus_>creationix: so the issue is, you need to store the candor callback in the same class as the uv_stream_t?
15:57:28  <creationix>I'm not particular to any solution
15:57:44  <piscisaureus_>creationix: so what you probably want to do is use a template
15:57:58  <creationix>the problem with my current solution is I can't typecast a uvTimer instance to a uvHandle instance
15:58:09  <creationix>I looked at templates
15:58:12  <creationix>not sure how that helps
15:58:22  <creationix>I don't know the original type
15:59:02  <piscisaureus_>well
15:59:34  <piscisaureus_>creationix: so you mean, you cannot upcast uvHandle to uvTimer
15:59:51  <creationix>it's stored as a void* in the CData that the script has
15:59:53  <piscisaureus_>creationix: you should not need to - just make sure you have multiple versions of onclose
16:00:13  <creationix>the problem is what do I typecast the void* to
16:00:20  <creationix>I don't know if it's a uvTimer or uvHandle
16:00:24  <piscisaureus_>ah, right
16:00:29  <creationix>(well, in this case it's easy, there are no uvHandle instances)
16:00:37  <creationix>but later when I have uvTcp and uvPipe
16:01:01  <piscisaureus_>yeah, you have to remember the type somehow
16:01:02  <creationix>in libuv it's ok, I can cast a uv_timer_t to a uv_handle_t and use it as a uv_handle_t
16:01:41  <creationix>so maybe wrap the class instance in a struct
16:02:00  <creationix>{int type, uvHandle* handle}
16:02:10  <piscisaureus_>or use a base class
16:02:15  <creationix>and then do a switch on the type?
16:02:41  <piscisaureus_>class uvHandle {
16:02:42  <piscisaureus_> HandleType type
16:02:42  <piscisaureus_>}
16:02:42  <piscisaureus_>class uvPipe: public uvHandle {
16:03:10  <creationix>will that work
16:03:18  <piscisaureus_>why not?
16:03:40  <creationix>that's still typecasting to a bast class type
16:03:47  <piscisaureus_>in noe
16:04:03  <creationix>I can't get at the type member without first typecasting the void*
16:04:10  <piscisaureus_>sure
16:04:20  <piscisaureus_>that's the downside of having only a void pointer :-)
16:04:40  <piscisaureus_>so what you would do is typecast the CData to uvHandle
16:04:47  <piscisaureus_>then get the type
16:04:54  <piscisaureus_>and then typecast again to the actual type.
16:05:04  <piscisaureus_>node basically does the same btw
16:05:10  <creationix>so members are safe to access, just not methods?
16:05:49  <piscisaureus_>if you don't use multiple inheritance and you make sure that uvPipe extends uvHandle
16:05:52  <indutny>piscisaureus_: CWrapper class has virtual destructor
16:06:10  <indutny>piscisaureus_: I think things are little bit more complicated with that
16:06:31  <piscisaureus_>can you show me the api?
16:06:44  <indutny>piscisaureus_: better ask creationix , he has much more examples
16:07:04  <indutny>piscisaureus_: https://github.com/indutny/candor/blob/master/test/test-api.cc#L93
16:07:13  <indutny>piscisaureus_: and following lines
16:07:40  <piscisaureus_>I don't see any problems
16:07:42  <creationix>piscisaureus_, https://github.com/indutny/candor/blob/master/include/candor.h#L233-256
16:07:48  <piscisaureus_>that's what a virtual destructor is for
16:08:04  <piscisaureus_>and virtual functions in general
16:08:22  <creationix>ok, so typecast void* to the base uvHandle, look up the type and then typecast to the right type?
16:08:26  <piscisaureus_>so you can downcast but when you do that the right method still gets called
16:08:33  <piscisaureus_>creationix: yeah
16:08:53  <creationix>wait, virtual functions work when downcast
16:08:55  <creationix>what's downcast
16:09:29  <piscisaureus_>if you have class A: public B;
16:09:43  <piscisaureus_>A* a = new A();
16:09:55  <piscisaureus_>B* b = A; // Downcast
16:10:14  <creationix>s/= A/= a/ ?
16:10:27  <piscisaureus_>yeah
16:10:51  <piscisaureus_>b->foo() // if foo is declared virtual, a::foo is called, otherwise b::foo is called
16:10:56  <creationix>ok, so I have
16:11:22  <creationix>what's the difference between a::foo and b::foo?
16:11:27  <creationix>aren't they the same function
16:11:30  <creationix>since it inherits
16:11:42  <piscisaureus_>well, if you overload foo() in a then they are not.
16:11:48  <piscisaureus_>so what you could even do is this
16:12:16  <piscisaureus_>oh nvm
16:13:10  <creationix>void* b = new B();
16:13:21  <creationix>a = (A*)b
16:13:27  <creationix>a->foo() // This breaks
16:13:48  <creationix>would making foo be virtual help?
16:13:49  <piscisaureus_>creationix: does not break if A is a base class of B or vice versa.
16:13:58  <creationix>B inherits from A
16:14:10  <creationix>and yes it breaks, my offsets are all messed up
16:14:52  <piscisaureus_>creationix: where?
16:15:20  <creationix>it calls the right function
16:15:25  <creationix>but the member values are wrong
16:16:06  <creationix>hmm, maybe it's because I override the "handle" member
16:16:18  <creationix>if uv_handle_t handle in uvHandle
16:16:24  <creationix>and uv_timer_t handle in uvTimer
16:16:52  <creationix>maybe I need to use a union struct as that member and not override it
16:17:02  <piscisaureus_>creationix: an union struct seems wrong to me.
16:17:50  <creationix>use the uv_any_handle?
16:18:20  <piscisaureus_>naah
16:18:44  <piscisaureus_>creationix: I am somewhat surprised that the compiler does not reject what you are doing
16:19:12  <creationix>it's void* how would it know
16:19:17  <creationix>there is no type saftey
16:20:14  <piscisaureus_>if you force it to have a subclass with a different layout as your base class it should barge
16:20:54  <piscisaureus_>aaah
16:20:59  <piscisaureus_>creationix: ghehe
16:21:05  <piscisaureus_>creationix: the handle member is private
16:21:15  <piscisaureus_>creationix: so you end up with two handles in uvTimer
16:21:27  <indutny>hah
16:21:28  <piscisaureus_>one uv_handle_t that is visible only to uvHandle
16:21:39  <creationix>uninitilized data
16:21:44  <piscisaureus_>and another uv_timer_t that is visible to uvTimer
16:21:46  <creationix>that would explain the bogous values
16:22:00  <creationix>ok, so everything has to be public
16:22:01  <piscisaureus_>creationix: you should not put uv_handle_t in uvHandle at all.
16:22:13  <piscisaureus_>creationix: no, if you do that the compiler will reject your code
16:22:42  <creationix>well if I don't have handle at all
16:22:47  <piscisaureus_>creationix: instead you should implement UvClose in every subclass of UvHandle (you can speed that up with template)
16:22:50  <creationix>how will uvHandle::Close get at handle?
16:23:15  <piscisaureus_>creationix: or what you could do is have a virtual function uv_handle_t* getHandle()
16:23:21  <piscisaureus_>and implement that in all subclasses
16:23:33  <piscisaureus_>so you can call `uv_close(getHandle())`
16:24:00  <creationix>what about the callbacks
16:24:04  <creationix>can those stay privite
16:24:07  <creationix>(private
16:24:15  <creationix>since they are only set or read by the same class
16:24:42  <piscisaureus_>creationix: you cannot overload private members. So you have to take care not to end up with two copies.
16:24:54  <creationix>they won't overload
16:24:58  <creationix>the callback names will be unique
16:24:59  <piscisaureus_>then it's fine
16:25:15  <creationix>ok, I like the getHandle() idea
16:25:19  <creationix>less code duplication
16:25:27  <piscisaureus_>creationix: actually, I don't really like it that much :-)
16:25:32  <creationix>slow?
16:25:32  <piscisaureus_>it's an extra pointer in your class
16:25:40  <piscisaureus_>yes, and an extra indirection
16:25:50  <creationix>and virtual functions are the slowest right
16:25:56  <piscisaureus_>yes
16:26:08  <piscisaureus_>although - it's not likely that it will really hurt in this case
16:26:15  <creationix>ok, so would the template way work?
16:26:27  <piscisaureus_>creationix: let me hammer something out
16:26:37  <creationix>what I don't want is to have to copy-paste functions for all the stream methods into every type that inherits from stream
16:28:33  <piscisaureus_>a sec
16:31:16  <piscisaureus_>We never really fixed this in node btw
16:31:19  <piscisaureus_>but that does not have to matter
16:32:46  <indutny>crap, that GC bug makes me angry
16:40:26  <creationix>indutny, still need a Object::GetKeys API
16:40:42  <creationix>last night I ended up compiling a small script and using keysof
16:40:47  <creationix>it was ugly
16:41:39  <indutny>creationix: ok
16:41:48  <indutny>I'll do it after I'll fix this stupid bug
17:11:49  <piscisaureus_>creationix: what does the uv api that registers runtime functions look like?
17:11:57  <creationix>?
17:12:08  <piscisaureus_>creationix: so in node we have NODE_SET_METHOD
17:12:18  <creationix>oh, candor API you mean
17:12:22  <piscisaureus_>yeah
17:12:39  <creationix>https://github.com/creationix/candor.io/blob/master/src/luv_handle.cc#L23
17:12:44  <creationix>just set a function as a property
17:12:51  <creationix>there are no methods in candor, no "this"
17:16:31  <piscisaureus_>creationix: looking at it you can be sure that if the Close callback is made, you know the type of CData
17:17:00  <creationix>how do
17:17:09  <creationix>all uv types inherit close from uv_handle_t
17:17:19  <piscisaureus_>yeah, so we are going to can that :-)
17:17:43  <creationix>what, the massive switch statement for uv_close?
17:18:11  <creationix>what about the stream functions
17:18:17  <creationix>those are more general and a lot of code to wrap
17:18:51  <piscisaureus_>creationix: I am making a template for it
17:19:21  <piscisaureus_>creationix: sorry, I have to go
17:19:21  <creationix>ok
17:19:23  <piscisaureus_>forgot :-(
17:19:30  <piscisaureus_>creationix: will finish it tonight
17:19:34  <creationix>ok, I'll try a template
17:19:36  <piscisaureus_>I assume you're not out of work :-)
17:19:42  <creationix>heh
17:19:56  <piscisaureus_>creationix: the trick is to have no UvHandle that is the base class to UvAnything
17:20:08  <piscisaureus_>just have a template that generates all these methods
17:20:15  <creationix>right
17:27:40  <piscisaureus_>creationix: https://gist.github.com/2045459
17:28:05  <piscisaureus_>creationix: probably you could also partially template-ify the init() method
17:29:44  <indutny>going to sleep guys :)
17:29:45  <indutny>ttyl
17:29:50  * indutnychanged nick to indutny_sleeping
17:35:17  * piscisaureus_quit (Ping timeout: 255 seconds)
18:31:46  * karterkquit (Remote host closed the connection)
18:34:33  * karterkjoined
18:42:13  * karterkquit (Remote host closed the connection)
22:49:14  * piscisaureus_joined
23:37:41  * piscisaureus_quit (Quit: ~ Trillian Astra - www.trillian.im ~)