-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to convert multiple impl class
to base protocol
type?
#136
Comments
I'm know, that i can make that working by that: let playerSession = PlayerSession.new()
let playerProtocol = playerSession.toProtocol()
resolveBase((connect: playerProtocol.connect, disconnect: playerProtocol.disconnect)) but isn't that ugly way? |
The features of protocol follow the ones of interface in other languages, so I'm not planning to make a feature that interface doesn't have. I guess a procedure that requires |
Sorry, my misunderstanding. protocol Animal:
proc eat
protocol CanFly:
proc fly
class Cat impl Animal:
proc eat =
discard
class Bird impl (Animal, CanFly):
proc eat =
discard
proc fly =
discard
let
cat = Cat.new()
bird = Bird.new()
var animals: seq[Animal] = @[]
animals.add cat.toProtocol() # type: tuple[eat: proc()]
# not compiled!
animals.add bird.toProtocol() # type: tuple[eat: proc(), fly: proc()] I'll fix this problem somehow. |
Yeah, that's what i originally meant. Seem's like converting is hard, because as i think we can lose original inheritance of class. For example, when we even has way to convert for animal in animals:
echo animal.isInstanceOf(Bird) ## false even when original class is `Bird` ? |
The return value of |
@griffith1deady |
So, sadly we never can get feature like that in JVM? val sender = (event.handler as NetHandlerPlayServer).playerEntity
|
Does that mean the conversion from protocol to class, not from class to protocol? I want to make it too, but I still don't come up with the way to implement it. |
Defining a |
Yeah, but not only from protocol to class, but two way conversion. Like class to protocol with converters (for auto picking correct protocol automatically, like does in other languages) and itself from protocol to class. |
About realization: I'm not sure in what way you make conversion from class to protocol, but if you make that like |
How I made the conversion from class to protocol is probably simpler than you think it is. |
I made #139 for this issue with a draft. |
how about making protocol's internally storing class reference? protocol Session:
proc connect()
proc disconnect() would be expanded into something like: type Session[T: ref object] = tuple[self: T, connect: proc(), disconnect: proc()] and then we can introduce something like proc classCast[T: tuple, C: ref object](protocol: T, class: typedesc[C]): C = protocol.self and we can make that working for non-ref classes easily by something like: |
@glassesneo just friendly ping |
Thank you for your suggestion, but something suddenly came up and I have to concentrate on my another project for approximately 2 months. |
@glassesneo import oolib
proc getEnvironment[T: proc](
procedure: T
): pointer = {.emit: "`result` = `procedure`.ClE_0;".}
proc getProcedure[T: proc](
procedure: T
): pointer {.inline.} = {.emit: "`result` = `procedure`.ClP_0;".}
protocol ReferenceInjection:
proc resolve(): string
class Injection impl (ReferenceInjection):
var count: int
proc resolve(): string =
return "Injected"
type InjectionEnvironment = object
sup: RootObj
colonstate: int
self: Injection
let referenceObject = Injection.new(count = 5)
let reference = referenceObject.toProtocol()
echo reference.resolve is proc(): string {.closure.} # true
echo reference.resolve is proc(): string {.nimcall.} # false
let referenceEnvironment = getEnvironment(reference.resolve)
let referenceProcedure = getProcedure(reference.resolve)
var environmentReference: Injection
copyMem(addr environmentReference, cast[pointer](cast[int](referenceEnvironment) + 16), sizeof(pointer))
echo referenceEnvironment.repr() # 00007F040D13F060
echo referenceProcedure.repr() # 000063E7C3BBE1F0
echo resolve.repr() # 000063E7C3BBE1E0
echo referenceObject.repr() # Injection(count: 5)
echo environmentReference.repr # Injection(count: 5)
var env: InjectionEnvironment
copyMem(addr env, referenceEnvironment, sizeof(InjectionEnvironment))
echo env.repr # InjectionEnvironment(sup: RootObj(), colonstate: 0, self: Injection(count: 5))
doAssert(referenceObject.count == 5 and env.self.count == 5, "Injection count is not equal")
# Assertion never failed.
echo env.self of Injection # true
it's a very unsafe code, but i can live with it. |
Thank you for your understanding. I'm glad there is something that uses my work! I'll be back in two months. |
Hi! I'm trying to figure how i can make that code work:
Error message:
As i see, by default there way todo this doesn't exists. My strange idea in generating conversion procedure for each procotol type for class, like
playerSession.toSession()
,playerSession.toReadable()
. Or exists some better way?The text was updated successfully, but these errors were encountered: