Add ParcelManager to HippoClient
This commit is contained in:
@@ -3,6 +3,7 @@ A simple client that just says hello to people
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import pprint
|
||||||
from contextlib import aclosing
|
from contextlib import aclosing
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@@ -30,6 +31,11 @@ async def amain():
|
|||||||
start_location=os.environ.get("HIPPO_START_LOCATION", "last"),
|
start_location=os.environ.get("HIPPO_START_LOCATION", "last"),
|
||||||
)
|
)
|
||||||
print("I'm here")
|
print("I'm here")
|
||||||
|
|
||||||
|
# Wait until we have details about parcels and print them
|
||||||
|
await client.main_region.parcel_manager.parcels_downloaded.wait()
|
||||||
|
pprint.pprint(client.main_region.parcel_manager.parcels)
|
||||||
|
|
||||||
await client.send_chat("Hello World!", chat_type=ChatType.SHOUT)
|
await client.send_chat("Hello World!", chat_type=ChatType.SHOUT)
|
||||||
client.session.message_handler.subscribe("ChatFromSimulator", _respond_to_chat)
|
client.session.message_handler.subscribe("ChatFromSimulator", _respond_to_chat)
|
||||||
# Example of how to work with caps
|
# Example of how to work with caps
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ from hippolyzer.lib.base.xfer_manager import XferManager
|
|||||||
from hippolyzer.lib.client.asset_uploader import AssetUploader
|
from hippolyzer.lib.client.asset_uploader import AssetUploader
|
||||||
from hippolyzer.lib.client.inventory_manager import InventoryManager
|
from hippolyzer.lib.client.inventory_manager import InventoryManager
|
||||||
from hippolyzer.lib.client.object_manager import ClientObjectManager, ClientWorldObjectManager
|
from hippolyzer.lib.client.object_manager import ClientObjectManager, ClientWorldObjectManager
|
||||||
|
from hippolyzer.lib.client.parcel_manager import ParcelManager
|
||||||
from hippolyzer.lib.client.state import BaseClientSession, BaseClientRegion, BaseClientSessionManager
|
from hippolyzer.lib.client.state import BaseClientSession, BaseClientRegion, BaseClientSessionManager
|
||||||
|
|
||||||
|
|
||||||
@@ -47,6 +48,8 @@ class ClientSettings(Settings):
|
|||||||
USER_AGENT: str = SettingDescriptor(f"Hippolyzer/v{version('hippolyzer')}")
|
USER_AGENT: str = SettingDescriptor(f"Hippolyzer/v{version('hippolyzer')}")
|
||||||
SEND_AGENT_UPDATES: bool = SettingDescriptor(True)
|
SEND_AGENT_UPDATES: bool = SettingDescriptor(True)
|
||||||
"""Generally you want to send these, lots of things will break if you don't send at least one."""
|
"""Generally you want to send these, lots of things will break if you don't send at least one."""
|
||||||
|
AUTO_REQUEST_PARCELS: bool = SettingDescriptor(True)
|
||||||
|
"""Automatically request all parcel details when connecting to a region"""
|
||||||
|
|
||||||
|
|
||||||
class HippoCapsClient(CapsClient):
|
class HippoCapsClient(CapsClient):
|
||||||
@@ -121,6 +124,7 @@ class HippoClientRegion(BaseClientRegion):
|
|||||||
self.xfer_manager = XferManager(proxify(self), self.session().secure_session_id)
|
self.xfer_manager = XferManager(proxify(self), self.session().secure_session_id)
|
||||||
self.transfer_manager = TransferManager(proxify(self), session.agent_id, session.id)
|
self.transfer_manager = TransferManager(proxify(self), session.agent_id, session.id)
|
||||||
self.asset_uploader = AssetUploader(proxify(self))
|
self.asset_uploader = AssetUploader(proxify(self))
|
||||||
|
self.parcel_manager = ParcelManager(proxify(self))
|
||||||
self.objects = ClientObjectManager(self)
|
self.objects = ClientObjectManager(self)
|
||||||
self._llsd_serializer = LLSDMessageSerializer()
|
self._llsd_serializer = LLSDMessageSerializer()
|
||||||
self._eq_task: Optional[asyncio.Task] = None
|
self._eq_task: Optional[asyncio.Task] = None
|
||||||
@@ -226,6 +230,9 @@ class HippoClientRegion(BaseClientRegion):
|
|||||||
self.update_caps(await seed_resp.read_llsd())
|
self.update_caps(await seed_resp.read_llsd())
|
||||||
|
|
||||||
self._eq_task = asyncio.create_task(self._poll_event_queue())
|
self._eq_task = asyncio.create_task(self._poll_event_queue())
|
||||||
|
|
||||||
|
if self.session().session_manager.settings.AUTO_REQUEST_PARCELS:
|
||||||
|
_ = asyncio.create_task(self.parcel_manager.request_dirty_parcels())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Let consumers who were `await`ing the connected signal know there was an error
|
# Let consumers who were `await`ing the connected signal know there was an error
|
||||||
if not self.connected.done():
|
if not self.connected.done():
|
||||||
|
|||||||
@@ -138,12 +138,13 @@ class ParcelManager:
|
|||||||
# Append the grid to the neighbour testing queue
|
# Append the grid to the neighbour testing queue
|
||||||
neighbor_test_queue.append(new_pos)
|
neighbor_test_queue.append(new_pos)
|
||||||
|
|
||||||
async def request_parcels_if_dirty(self) -> Tuple[Parcel, ...]:
|
async def request_dirty_parcels(self) -> Tuple[Parcel, ...]:
|
||||||
if self._parcels_dirty:
|
if self._parcels_dirty:
|
||||||
return await self.request_all_parcels()
|
return await self.request_all_parcels()
|
||||||
return tuple(self.parcels)
|
return tuple(self.parcels)
|
||||||
|
|
||||||
async def request_all_parcels(self) -> Tuple[Parcel, ...]:
|
async def request_all_parcels(self) -> Tuple[Parcel, ...]:
|
||||||
|
await self.overlay_complete.wait()
|
||||||
# Because of how we build up the parcel index map, it's safe for us to
|
# Because of how we build up the parcel index map, it's safe for us to
|
||||||
# do this instead of keeping track of seen IDs in a set or similar
|
# do this instead of keeping track of seen IDs in a set or similar
|
||||||
last_seen_parcel_index = 0
|
last_seen_parcel_index = 0
|
||||||
@@ -164,9 +165,11 @@ class ParcelManager:
|
|||||||
# Wait for all parcel properties to come in
|
# Wait for all parcel properties to come in
|
||||||
await asyncio.gather(*futs)
|
await asyncio.gather(*futs)
|
||||||
self.parcels_downloaded.set()
|
self.parcels_downloaded.set()
|
||||||
|
self._parcels_dirty = False
|
||||||
return tuple(self.parcels)
|
return tuple(self.parcels)
|
||||||
|
|
||||||
async def request_parcel_properties(self, pos: Vector2) -> Parcel:
|
async def request_parcel_properties(self, pos: Vector2) -> Parcel:
|
||||||
|
await self.overlay_complete.wait()
|
||||||
seq_id = self._next_seq
|
seq_id = self._next_seq
|
||||||
# Register a wait on a ParcelProperties matching this seq
|
# Register a wait on a ParcelProperties matching this seq
|
||||||
parcel_props_fut = self._region.message_handler.wait_for(
|
parcel_props_fut = self._region.message_handler.wait_for(
|
||||||
@@ -176,7 +179,7 @@ class ParcelManager:
|
|||||||
)
|
)
|
||||||
# We don't care about when we receive an ack, we only care about when we receive the parcel props
|
# We don't care about when we receive an ack, we only care about when we receive the parcel props
|
||||||
_ = self._region.circuit.send_reliable(Message(
|
_ = self._region.circuit.send_reliable(Message(
|
||||||
"RequestParcelProperties",
|
"ParcelPropertiesRequest",
|
||||||
Block("AgentData", AgentID=self._region.session().agent_id, SessionID=self._region.session().id),
|
Block("AgentData", AgentID=self._region.session().agent_id, SessionID=self._region.session().id),
|
||||||
Block(
|
Block(
|
||||||
"ParcelData",
|
"ParcelData",
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ class TestParcelOverlay(unittest.IsolatedAsyncioTestCase):
|
|||||||
async def test_request_parcel_properties(self):
|
async def test_request_parcel_properties(self):
|
||||||
for msg in self.test_msgs:
|
for msg in self.test_msgs:
|
||||||
self.handler.handle(msg)
|
self.handler.handle(msg)
|
||||||
req_task = asyncio.create_task(self.parcel_manager.request_parcels_if_dirty())
|
req_task = asyncio.create_task(self.parcel_manager.request_dirty_parcels())
|
||||||
# HACK: Wait for requests to be sent out
|
# HACK: Wait for requests to be sent out
|
||||||
await asyncio.sleep(0.01)
|
await asyncio.sleep(0.01)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user