CK Tree Node

  • CKTreeNode it's our representation of a component in the new component tree.
    • It has a unique identifier
    • Holds CKComponentScopeHandle (state + controller) if needed.
    • Being constructed by the infra when we call buildComponentTree:
    • The equivalent of CKComponentScopeFrame in our new infrastructure
  • CKTreeNodeWithChild
    • Holds one child and its component key
  • CKTreeNodeWithChildren
    • Holds a map of component key → tree nodes to; component key is a tuple of <component class, counter>
  • Every component (even non-render) has a tree node once there is a render component in the tree

Example:

@implementation AComponent
{
NSString *_text;
}
+ (instancetype)newWithText:(NSString *)text
{
auto const c = [super new];
if (c) {
c->_text = text;
}
return c;
}
- (CKComponent *)render:(id)state
{
return [CKTextComponent newWithText:text];
}
@end

Will translate into this tree:

Root Node

Scopes (non-render world)

What do we have without CKRenderComponent?

  • CKComponentScope
    • Being created on the stack
    • Has 3 parameters: CKComponentScope(class, identifier, initialStateBlock)
  • CKComponentScopeFrame
    • An obj-c object. Represent a component with scope in the component tree
  • CKComponentScopeHandle
    • Holds the state, the controller, an identifier and the component.
    • Each CKComponentScopeFrame holds CKComponentScopeHandle; you can see it as the value of the frame tree

Example:

@implementation AComponent
- (instancetype)newWithText:(NSString *)text
{
CKComponentScope scope(self);
auto const c =
[super newWithComponent:
[CKTextComponent
newWithText:text]];
if (c) {
// Do something
}
return c;
}
@end

Will translate into this tree:

Component Tree

We can see the the component tree doesn't have any representation for the CKTextComponent.

Build Component Tree

  • As we just saw in the, we build a full component tree (CKTreeNode) in case that we have a render component in the tree.
  • The way we build the component tree is by calling the following method on the root component:
- (void)buildComponentTree:(id<CKTreeNodeWithChildrenProtocol>)parent
previousParent:(id<CKTreeNodeWithChildrenProtocol>)previousParent
params:(const CKBuildComponentTreeParams &)params
config:(const CKBuildComponentConfig &)config
hasDirtyParent:(BOOL)hasDirtyParent;
  • Each component is responsible to build its tree node and continue the recursion for its children.
  • This method is responsible to call the render method on render components (or reuse the previous component if possible).
  • We implemented this method in all our base classes:
    • CKComponent
    • CKCompositeComponent
    • CKRenderComponent
    • CKRenderWithChildrenComponent