Skip to content

Commit

Permalink
Lazy loading for stream branches & commits (#200)
Browse files Browse the repository at this point in the history
* only fetch branches on reload

* initial load

* load on stream selection

* refactor get_item_by_index

* fix resetting commit selection on default branch

* refactor load_stream_branches

* clean logs

* explicit return

---------

Co-authored-by: Soylu <[email protected]>
Co-authored-by: Jedd Morgan <[email protected]>
  • Loading branch information
3 people authored Jul 29, 2024
1 parent 15bd3f5 commit 8c3885e
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 31 deletions.
41 changes: 16 additions & 25 deletions bpy_speckle/operators/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,28 +137,8 @@ def add_user_stream(user: SpeckleUserObject, stream: Stream):

_report(f"Adding stream {s.id} - {s.name}")

if not stream.branches:
return

# branches = [branch for branch in stream.branches.items if branch.name != "globals"]
for b in stream.branches.items:
branch = cast(SpeckleBranchObject, s.branches.add())
branch.name = b.name
branch.id = b.id
branch.description = b.description or ""

if not b.commits:
continue

for c in b.commits.items:
commit: SpeckleCommitObject = branch.commits.add()
commit.id = commit.name = c.id
commit.message = c.message or ""
commit.author_name = c.authorName
commit.author_id = c.authorId
commit.created_at = c.createdAt.strftime("%Y-%m-%d %H:%M:%S.%f%Z") if c.createdAt else ""
commit.source_application = str(c.sourceApplication)
commit.referenced_object = c.referencedObject
if stream.branches:
s.load_stream_branches(stream)


class LoadUserStreams(bpy.types.Operator):
Expand Down Expand Up @@ -195,12 +175,23 @@ def load_user_stream(self, context: Context) -> None:
_report("Zero projects found")
return


active_stream_id = None
if active_stream := user.get_active_stream():
active_stream_id = active_stream.id
elif len(user.streams) > 0:
active_stream_id = user.streams[0].id

user.streams.clear()

for s in streams:
for i, s in enumerate(streams):
assert(s.id)
sstream = client.stream.get(id=s.id, branch_limit=self.branch_limit, commit_limit=10)
add_user_stream(user, sstream)
load_branches = s.id == active_stream_id if active_stream_id else i == 0
if load_branches:
sstream = client.stream.get(id=s.id, branch_limit=self.branch_limit, commit_limit=10)
add_user_stream(user, sstream)
else:
add_user_stream(user, s)

restore_selection_state(speckle)

Expand Down
51 changes: 45 additions & 6 deletions bpy_speckle/properties/scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
IntProperty,
)

from bpy_speckle.clients import speckle_clients
from specklepy.core.api.models import Stream

class SpeckleSceneObject(bpy.types.PropertyGroup):
name: bpy.props.StringProperty(default="") # type: ignore

Expand Down Expand Up @@ -58,6 +61,28 @@ def get_active_commit(self) -> Optional[SpeckleCommitObject]:
return None

class SpeckleStreamObject(bpy.types.PropertyGroup):
def load_stream_branches(self, sstream: Stream):
self.branches.clear()
# branches = [branch for branch in stream.branches.items if branch.name != "globals"]
for b in sstream.branches.items:
branch = cast(SpeckleBranchObject, self.branches.add())
branch.name = b.name
branch.id = b.id
branch.description = b.description or ""

if not b.commits:
continue

for c in b.commits.items:
commit: SpeckleCommitObject = branch.commits.add()
commit.id = commit.name = c.id
commit.message = c.message or ""
commit.author_name = c.authorName
commit.author_id = c.authorId
commit.created_at = c.createdAt.strftime("%Y-%m-%d %H:%M:%S.%f%Z") if c.createdAt else ""
commit.source_application = str(c.sourceApplication)
commit.referenced_object = c.referencedObject

def get_branches(self, context):
if self.branches:
BRANCHES = cast(Iterable[SpeckleBranchObject], self.branches)
Expand Down Expand Up @@ -89,8 +114,17 @@ def get_active_branch(self) -> Optional[SpeckleBranchObject]:
return None

class SpeckleUserObject(bpy.types.PropertyGroup):
def fetch_stream_branches(self, context: bpy.types.Context, stream: SpeckleStreamObject):
speckle = context.scene.speckle
client = speckle_clients[int(speckle.active_user)]
sstream = client.stream.get(id=stream.id, branch_limit=100, commit_limit=10) # TODO: refactor magic numbers
stream.load_stream_branches(sstream)

def stream_update_hook(self, context: bpy.types.Context):
selection_state.selected_stream_id = SelectionState.get_item_id_by_index(self.streams, self.active_stream)
stream = SelectionState.get_item_by_index(self.streams, self.active_stream)
selection_state.selected_stream_id = stream.id
if len(stream.branches) == 0: # do not reload on selection, same as the old behavior
self.fetch_stream_branches(context, stream)

server_name: StringProperty(default="SpeckleXYZ") # type: ignore
server_url: StringProperty(default="https://speckle.xyz") # type: ignore
Expand Down Expand Up @@ -223,11 +257,16 @@ class SelectionState:

@staticmethod
def get_item_id_by_index(collection: bpy.types.PropertyGroup, index: Union[str, int]) -> Optional[str]:
# print(list(collection.items()))
selected_index = int(index)
for index, (_, item) in enumerate(collection.items()):
if index == selected_index:
return item.id
if item := SelectionState.get_item_by_index(collection, index):
return item.id
return None

@staticmethod
def get_item_by_index(collection: bpy.types.PropertyGroup, index: Union[str, int]) -> Optional[bpy.types.PropertyGroup]:
items = collection.values()
i = int(index)
if 0 <= i <= len(items):
return items[i]
return None

@staticmethod
Expand Down

0 comments on commit 8c3885e

Please sign in to comment.