-
Notifications
You must be signed in to change notification settings - Fork 2
Integration prototype #1
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
Open
rd4com
wants to merge
8
commits into
lsh:main
Choose a base branch
from
rd4com:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 3 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
f488f63
Integration prototype
rd4com 05ebe95
Integration prototype
rd4com 0db656e
update
rd4com df88fbb
add implementation with variant
rd4com 3ff2e27
two other prototypes
rd4com efde56b
✨
rd4com 5f83b02
update
rd4com cb6471a
update
rd4com File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| #Used for props, should be replaced by parametrized props | ||
| struct AnyThing: | ||
| var p:Pointer[Int] | ||
| var ref_count: Pointer[Int] | ||
| var free_function: Pointer[Int] | ||
|
|
||
| fn __init__[T:CollectionElement](inout self,arg:T): | ||
| self.p = __type_of(self.p).alloc(1) | ||
| var tmp = UnsafePointer[T].alloc(1) | ||
| initialize_pointee_move(tmp,arg) | ||
| self.p[]=int(tmp) | ||
|
|
||
| self.free_function = __type_of(self.free_function).alloc(1) | ||
| fn f(to_free :Int)escaping->None: | ||
| var tmp_ = UnsafePointer[T](address=to_free) | ||
| destroy_pointee(tmp_) | ||
| tmp_.free() | ||
| var ptr = UnsafePointer[fn(Int)escaping->None].alloc(1) | ||
| initialize_pointee_move[fn(Int)escaping->None](ptr,f) | ||
| self.free_function[]=int(ptr) | ||
|
|
||
| self.ref_count=Pointer[Int].alloc(1) | ||
| self.ref_count[]=1 | ||
|
|
||
| fn deref[T:CollectionElement](inout self)->T: | ||
| return UnsafePointer[T](address=self.p[])[] | ||
|
|
||
| fn __getitem__[T:CollectionElement](inout self)->T: | ||
| return UnsafePointer[T](address=self.p[])[] | ||
|
|
||
| fn set[T:CollectionElement](inout self,arg:T): | ||
| UnsafePointer[fn(Int)escaping->None](address=self.free_function[])[](self.p[]) | ||
| destroy_pointee(UnsafePointer[fn(Int)escaping->None](address=self.free_function[])) | ||
| UnsafePointer[fn(Int)escaping->None](address=self.free_function[]).free() | ||
| fn f(to_free :Int)escaping->None: | ||
| var tmp_ = UnsafePointer[T](address=to_free) | ||
| destroy_pointee(tmp_) | ||
| tmp_.free() | ||
| var ptr = UnsafePointer[fn(Int)escaping->None].alloc(1) | ||
| initialize_pointee_move[fn(Int)escaping->None](ptr,f) | ||
| self.free_function[]=int(ptr) | ||
|
|
||
| var tmp = UnsafePointer[T].alloc(1) | ||
| initialize_pointee_move(tmp,arg) | ||
| self.p[]=int(tmp) | ||
|
|
||
| fn __copyinit__(inout self, other:Self): | ||
| self.ref_count = other.ref_count | ||
| self.p = other.p | ||
| self.ref_count[] += 1 | ||
| self.free_function=other.free_function | ||
|
|
||
| fn __moveinit__(inout self, owned other:Self): | ||
| self.ref_count = other.ref_count | ||
| self.p = other.p | ||
| self.free_function=other.free_function | ||
|
|
||
| fn __del__(owned self): | ||
| if self.ref_count[] == 1: | ||
| #print("del") | ||
| UnsafePointer[fn(Int)escaping->None]( | ||
| address=self.free_function[] | ||
| )[](self.p[]) | ||
| destroy_pointee( | ||
| UnsafePointer[fn(Int)escaping->None]( | ||
| address=self.free_function[] | ||
| ) | ||
| ) | ||
| UnsafePointer[fn(Int)escaping->None](address=self.free_function[]).free() | ||
| self.free_function.free() | ||
| self.p.free() | ||
| self.ref_count.free() | ||
| else: | ||
| self.ref_count[]-=1 | ||
| #print(self.ref_count[]) | ||
|
|
||
| #def MyFunc2(**args:Prop): | ||
| # val_a = args["arg_a"].deref[StringLiteral]() | ||
| # val_b = args["arg_b"].deref[Tuple[Int,Int]]() | ||
| # print(val_a) | ||
| # print(val_b.get[0](),val_b.get[1]()) | ||
| # | ||
| #def main(): | ||
| # MyFunc2(arg_a = "Hello world",arg_b = (1,2)) | ||
| # | ||
| # tmp = Prop(1.1) | ||
| # print(tmp.deref[Float64]()) | ||
| # cp = tmp | ||
| # cp.set("Hello world") | ||
| # print(tmp.deref[StringLiteral]()) | ||
| # for i in range(10): | ||
| # tmp2 = Prop(String("hello world")+str(i)) | ||
| # print(tmp2.deref[String]()) | ||
| # #tmp2.set(1/i) | ||
| # #print(tmp2.deref[Float64]()) | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
| # |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| from DomTree import * | ||
| from AnyThing import * | ||
| from DomEvent import * | ||
| alias PropsType = Dict[String,AnyThing] | ||
|
|
||
| trait Component(CollectionElement): | ||
| @staticmethod | ||
| fn component_name()->String:... | ||
| fn __init__(inout self): ... | ||
| fn event(inout self, e:DomEvent): ... | ||
| def render( | ||
| inout self, | ||
| owned props:PropsType | ||
| ) ->Element: ... | ||
|
|
||
| @value | ||
| struct Component_T: | ||
| var instance_name:String | ||
| var component_name: String | ||
| var props: PropsType | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,214 @@ | ||
| from Component import * | ||
| from DomTree import * | ||
| from python import Python | ||
| @value | ||
| struct Instances: | ||
| var states: Dict[ | ||
| String, #InstanceName | ||
| UnsafePointer[NoneType] | ||
| ] | ||
|
|
||
| fn __getitem__[ | ||
| T:Component, | ||
| n:StringLiteral | ||
| ](self)->UnsafePointer[T]: | ||
| try: | ||
| return self.states[n].bitcast[T]() | ||
| except e: ... | ||
| return UnsafePointer[T]() | ||
|
|
||
|
|
||
| @value | ||
| struct ComponentManager[*Ts:Component]: | ||
| var states: Dict[ | ||
| String, #InstanceName | ||
| UnsafePointer[NoneType] | ||
| ] | ||
| var types: Dict[String,String] #InstanceName,ComponentName | ||
| var previously_rendered_instances: List[String] #InstanceNames | ||
|
|
||
| fn __init__(inout self): | ||
| constrained[ | ||
| TsUniques[Ts](), | ||
| "Two components have the same name" | ||
| ]() | ||
|
|
||
| self.states = __type_of(self.states)() | ||
| self.types = __type_of(self.types)() | ||
| self.previously_rendered_instances = | ||
| __type_of(self.previously_rendered_instances)() | ||
|
|
||
|
|
||
| fn RenderIntoJson[First:Bool=False]( | ||
| inout self, | ||
| inout elements: Element, | ||
| )->PythonObject: | ||
| try: | ||
| var tmp_result = Python.evaluate("lambda **kwargs: kwargs")( | ||
| tag=elements.tag, | ||
| inner=[] | ||
| ) | ||
| if elements.tag == "TextNode": | ||
| tmp_result["value"]=elements.attributes["value"] | ||
| else: | ||
| for a in elements.attributes: | ||
| tmp_result[a[]]=elements.attributes[a[]] | ||
| for i in elements.inner: | ||
| if i[].isa[Element](): | ||
| tmp_result["inner"].append( | ||
| self.RenderIntoJson( | ||
| i[]._get_ptr[Element]()[] | ||
| ) | ||
| ) | ||
| @parameter | ||
| if First: return Python.import_module("json").dumps(tmp_result) | ||
| else: return tmp_result | ||
| except e: print("RenderToJson",e) | ||
| return None | ||
|
|
||
| fn RenderComponentsIntoElements[first:Bool]( | ||
| inout self, | ||
| inout arg: Element | ||
| ): | ||
| #TODO: check not instance_name rendered twice | ||
| @parameter | ||
| if first: self.previously_rendered_instances.clear() | ||
|
|
||
| if arg.component: | ||
| var tmp = arg.component._value_copy() | ||
| @parameter | ||
| fn loop[I:Int](): | ||
| if is_component[Ts[I]](tmp.component_name): | ||
| self.TsRenderInto[Ts[I]](arg,tmp) | ||
| unroll[loop,len(VariadicList(Ts))]() | ||
| _=tmp | ||
|
|
||
| for i in arg.inner: | ||
| if i[].isa[Element](): | ||
| if i[]._get_ptr[Element]()[].component: | ||
| var tmp = i[]._get_ptr[Element]()[] | ||
| self.RenderComponentsIntoElements[False](tmp) | ||
| i[]._get_ptr[Element]()[] = tmp | ||
|
|
||
| fn CreateInstance[T:Component]( | ||
| inout self, | ||
| c:Component_T | ||
| )->UnsafePointer[T]: | ||
| var tmp=UnsafePointer[T].alloc(1) | ||
| initialize_pointee_move(tmp,T()) | ||
| self.states[c.instance_name]=tmp.bitcast[NoneType]() | ||
| self.types[c.instance_name]=c.component_name | ||
| return tmp | ||
|
|
||
| fn GetInstance[T:Component]( | ||
| inout self, | ||
| c:Component_T | ||
| )->UnsafePointer[T]: | ||
| for k in self.states: | ||
| if k[] == c.instance_name: | ||
| try: | ||
| var tmp2= self.states[k[]].bitcast[T]() | ||
| return tmp2 | ||
| except e: print(e) | ||
| var tmp = self.CreateInstance[T](c) | ||
| return tmp | ||
|
|
||
| fn TsRenderInto[T:Component]( | ||
| inout self, | ||
| inout e:Element, | ||
| c: Component_T | ||
| ): | ||
| var instance = self.GetInstance[T](c)#T() | ||
| try: | ||
| var tmp=instance[].render(c.props) | ||
| tmp.attributes["data-instance_name"]=c.instance_name | ||
| e=tmp | ||
| except e:print("TsRenderInto",e) | ||
|
|
||
| self.previously_rendered_instances.append( | ||
| c.instance_name | ||
| ) | ||
|
|
||
| fn delete_instances[only_unrendered:Bool=False](inout self): | ||
| var deleted = Dict[String,Bool]() | ||
| for instance_name in self.states: | ||
| if self.types.find(instance_name[]): | ||
| try: | ||
| var tmp_ptr = self.states[instance_name[]] | ||
| var t= self.types[instance_name[]] | ||
| @parameter | ||
| fn loop[I:Int](): | ||
| if instance_name[] in deleted: return | ||
| if is_component[Ts[I]](t): | ||
| try: | ||
| @parameter | ||
| if only_unrendered: | ||
| var found = False | ||
| for p in self.previously_rendered_instances: | ||
| if p[]==instance_name[]: | ||
| found = True | ||
| if found: return | ||
| _=self.types.pop(instance_name[]) | ||
| deleted[instance_name[]]=True | ||
| destroy_pointee(tmp_ptr.bitcast[Ts[I]]()) | ||
| tmp_ptr.free() | ||
| except e:print("delete_instances/loop",e) | ||
| unroll[loop,len(VariadicList(Ts))]() | ||
| _=tmp_ptr | ||
| except e: print("delete_instances",e) | ||
| try: | ||
| print("__del__() :",len(deleted)) | ||
| for i in deleted: | ||
| var tmp_del = self.states.pop(i[]) | ||
| print("\t",i[]) | ||
| except e: print("delete_instances",e) | ||
| @parameter | ||
| if only_unrendered == False: | ||
| self.previously_rendered_instances= | ||
| __type_of(self.previously_rendered_instances)() | ||
| _=deleted | ||
| _=self.states | ||
| _=self.types | ||
|
|
||
| fn is_component[T:Component](name:String)->Bool: | ||
| return T.component_name()==name | ||
|
|
||
| fn TsEquals[T:Component,T2:Component]()->Bool: | ||
| return T.component_name() == T2.component_name() | ||
|
|
||
| fn TsIndex[*Ts:Component](name:String)->Int: | ||
| var result=-1 | ||
| @parameter | ||
| fn loop[I:Int](): | ||
| if is_component[Ts[I]](name): result = I | ||
| unroll[loop,len(VariadicList(Ts))]() | ||
| return result | ||
|
|
||
| fn TsCount[T:Component,*Ts:Component]()->Int: | ||
| var result=0 | ||
| @parameter | ||
| fn loop[I:Int](): | ||
| if TsEquals[Ts[I],T](): result += 1 | ||
| unroll[loop,len(VariadicList(Ts))]() | ||
| return result | ||
|
|
||
| fn TsUniques[*Ts:Component]()->Bool: | ||
| var result = True | ||
| @parameter | ||
| fn loop[I:Int](): | ||
| if TsCount[Ts[I],Ts]()>1: | ||
| result = False | ||
| unroll[loop,len(VariadicList(Ts))]() | ||
| return result | ||
|
|
||
| fn TsContains[*Ts:Component,name:StringLiteral]()->Bool: | ||
| var result = False | ||
| @parameter | ||
| fn loop[I:Int](): | ||
| result = result|TsEq[Ts[I],name]() | ||
| unroll[loop,len(VariadicList(Ts))]() | ||
| return result | ||
|
|
||
| fn TsEq[Ts:Component,arg:StringLiteral]()->Bool: | ||
| return Ts.component_name() == arg | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| from utils.variant import Variant | ||
| from Component import * | ||
| from ComponentManager import * | ||
|
|
||
| @value | ||
| struct DomEvent: | ||
| alias MouseEnter = "MouseEnter" | ||
| alias Click = "Click" | ||
| var target:String #TODO: id attribute | ||
| var type: String #TODO: "MouseEnter" | ||
| var name:String # On[DomEvent.Click]("name") | ||
| var data:String #TODO: json, depend on event type | ||
| var Instances: Instances | ||
|
|
||
| @value | ||
| struct EventHandler: | ||
| var type: StringLiteral | ||
| var instance_name:String | ||
| var event_name:String | ||
|
|
||
| fn On[e:StringLiteral](name:StringLiteral)->EventHandler: | ||
| return EventHandler(e,"",name) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's split this out as the start PR for this. In general I'm favorable towards this, though I don't think we need the
component_name, andrendershould befn, notdef.