public static void FillPoolWithChildrenViews <TView, TData>(IViewPool <TView, TData> pool, Transform parent, PrefabRef <TView> prefabRef, TView prefab, PresentOptions options) where TView : ReusableView { if (parent == null) { return; } foreach (var obj in parent) { var view = ((Transform)obj).GetComponent <TView>(); if (view != null) { if (view.prefabRef != null && view.prefabRef == prefab) { pool.AddViewToUse((TView)view.prefabRef, view); } else if (options.Has(PresentOptions.UseChildWithSameTypeAsView) && view.GetType() == prefabRef.ExtractType()) { view.prefabRef = prefab; pool.AddViewToUse((TView)view.prefabRef, view); } else if (options.Has(PresentOptions.UseChildWithSameNameAsView) && view.name == prefabRef.ExtractName()) { view.prefabRef = prefab; pool.AddViewToUse((TView)view.prefabRef, view); } } } }
void Start() { if (!CheckConfig()) { return; } if (UseDefaultViewSelection) { // create name dictionary viewNameDictionary = new Dictionary <string, GameObject>(); foreach (var item in configs) { viewNameDictionary.Add(item.name, item.viewTemplate); } } if (usePool) { var templates = new List <GameObject>(); foreach (var config in configs) { // add to list templates.Add(config.viewTemplate); } // get pool viewPool = ViewPoolManager.Instance.CreateDynamicPool(templates); } CreateBinding(); BindingUtility.AddBinding(bindingList, transform, out dataContext); }
public ListPresenter(IViewPool <TView, TData> pool, Action <TData, TView> onShow = null, Func <TView, float> unload = null, Func <TData, int> visualIdGetter = null, Func <TData, bool> needView = null, bool updateOnShow = true, bool disableOnRecycle = true ) : base(pool, onShow, unload) { if (visualIdGetter == null && typeof(Rui.IPresentableData).IsAssignableFrom(typeof(TData))) { this.visualIdGetter = data => ((Rui.IPresentableData)data).GetVisualId(); } else { this.visualIdGetter = visualIdGetter; } this.updateOnShow = updateOnShow; this.needView = needView; // if (disableOnRecycle) pool.AddRecycleAction(v => // { // v.SetActiveSafe(false); // return 0; // }); }
void Start() { // check if view template contains DataContext component if (viewTemplate.GetComponent <IDataContext>() == null) { Debug.LogError("ViewTemplate need IDataContext component", gameObject); return; } // get dynamic controller dynamicController = GetComponent <IDynamicController>(); if (dynamicController == null) { Debug.LogError("Need DynamicController component", gameObject); return; } if (usePool) { // get pool viewPool = ViewPoolManager.Instance.GetViewPool(viewTemplate); } else { // create local view pool viewPool = LocalViewPool.Create(transform); } CreateBinding(); BindingUtility.AddBinding(bindingList, transform, out dataContext); }
public static void FillPoolWithChildrenViews <TView, TData>(IViewPool <TView, TData> pool, Transform parent, Type viewType) where TView : ReusableView { foreach (var obj in parent) { var view = ((Transform)obj).GetComponent <TView>(); if (view != null && view.GetType() == viewType) { pool.AddViewToUse((TView)view.prefabRef, view); } } }
public DelayedViewPool(IViewPool viewPool) { if (viewPool == null) { throw new ArgumentNullException("viewPool"); } poolDictionary = new Dictionary <GameObject, Stack <GameObject> >(); instanceDictionary = new Dictionary <GameObject, GameObject>(); this.viewPool = viewPool; }
public static SimplePresentComponents <TView, T> Present <T, TView>( this IReactiveCollection <T> coll, Transform parent, PrefabRef <TView> prefab = default, Action <T, TView> show = null, Func <T, IEventStream> updater = null, Func <T, PrefabRef <TView> > prefabSelector = null, IViewPool <TView, T> pool = null, PresentOptions options = PresentOptions.UseChildWithSameTypeAsView, TableDelegates <TView> delegates = null ) where TView : ReusableView { var components = CreateBasicTableComponents(coll, parent, show, pool, prefab, prefabSelector, null, delegates, updater, options); var viewStorage = components.viewLoader; components.addConnection = coll.update.Subscribe(e => { switch (e.type) { case ReactiveCollectionEventType.Reset: viewStorage.UnloadAll(); viewStorage.ReloadAll(e.newData); break; case ReactiveCollectionEventType.Insert: viewStorage.LoadView(e.position, e.newItem); break; case ReactiveCollectionEventType.Remove: viewStorage.UnloadView(e.position); break; case ReactiveCollectionEventType.Set: viewStorage.UnloadView(e.position); viewStorage.LoadView(e.position, e.newItem); break; } }); viewStorage.ReloadAll(coll); // TODO think about how destroy should work components.addConnection = new AnonymousDisposable(() => components.viewLoader.UnloadAll()); components.animationsEnabled = true; return(components); }
void Start() { // check if view template contains DataContext component if (viewTemplate.GetComponent <IDataContext>() == null) { Debug.LogError("ViewTemplate need IDataContext component", gameObject); return; } if (usePool) { // get pool viewPool = ViewPoolManager.Instance.GetViewPool(viewTemplate); } CreateBinding(); BindingUtility.AddBinding(bindingList, transform, out dataContext); }
public void RemoveViewPool(IViewPool viewPool, GameObject viewPrefab) { if (viewPool == null) { throw new ArgumentNullException("viewPool"); } int instanceID = 0; if (viewPrefab == null) { // try search instanceID foreach (var kvp in poolDictionary) { if (kvp.Value == viewPool) { instanceID = kvp.Key; break; } } if (instanceID == 0) { Debug.LogWarning("ViewPrefab is null"); return; } } else { instanceID = viewPrefab.GetInstanceID(); } // check if prefab is valid if (!poolDictionary.ContainsKey(instanceID)) { Debug.LogWarningFormat("Unknown ViewPool for viewPrefab {0}", viewPrefab.name); return; } // remove it poolDictionary.Remove(instanceID); }
public void AddViewPool(IViewPool viewPool, GameObject viewPrefab) { if (viewPool == null) { throw new ArgumentNullException("viewPool"); } if (viewPrefab == null) { throw new ArgumentNullException("viewPrefab"); } int instanceID = viewPrefab.GetInstanceID(); // check if prefab is already added if (poolDictionary.ContainsKey(instanceID)) { Debug.LogWarningFormat("ViewPool for viewPrefab {0} is already added.", viewPrefab.name); return; } // add pool poolDictionary.Add(instanceID, viewPool); }
public SimplePresentComponents <TView, TData> GetPool(out IViewPool <TView, TData> pool) { pool = viewLoader.pool; return(this); }
public void StartSystem() { ViewPool = CreateViewPool(); OnPoolStarting(); }
public void Start(IObservableGroup @group) { ViewPool = CreateViewPool(); OnPoolStarting(); }
protected DefaultInjectablePooledViewResolverSystem(IPoolManager poolManager, IEventSystem eventSystem, IInstantiator instantiator) : base(poolManager, eventSystem, instantiator) { ViewPool = new InjectableViewPool(instantiator, PrefabTemplate); }
protected DefaultPooledViewResolverSystem(IPoolManager poolManager, IEventSystem eventSystem) : base(poolManager, eventSystem) { ViewPool = new ViewPool(PrefabTemplate); }
public static TableConnectionsAndComponents <TViewGroup, GroupItem <TGroup, TData, TView> > PresentGrouped <TData, TView, TGroup, TViewGroup>( IViewPort viewPort, IReactiveCollection <TData> collection, Func <TData, TGroup> grouper, IViewPool <TView, TData> viewPool, IViewPool <TViewGroup, TGroup> groupViewPool, Action <TData, TView> show, Action <TGroup, TViewGroup> showGroup, Func <IReactiveCollection <TData>, IScrollViewLayout> layoutFactory, Func <TGroup, TGroup, int> groupSort, Func <TData, TData, int> itemSort, LinearLayoutSettings settings, TableDelegates <TView> delegates = null, TableDelegates <TViewGroup> groupViewDelegates = null ) where TView : ReusableView where TViewGroup : ReusableView { float LayoutBoundingsFactory(GroupItem <TGroup, TData, TView> item) => item.layout.size.value + settings.mainSize; var grouped = new ReactiveCollection <GroupItem <TGroup, TData, TView> >(); var groupLayout = LinearVariableSizeLayout.Create(grouped, LayoutBoundingsFactory, settings); var groupComponents = new TableConnectionsAndComponents <TViewGroup, GroupItem <TGroup, TData, TView> >() { layout = groupLayout, collection = grouped, viewPort = viewPort, viewLoader = new LinearViewLoader <TViewGroup, GroupItem <TGroup, TData, TView> >( new ViewPoolProxyMap <TViewGroup, GroupItem <TGroup, TData, TView>, TGroup> { viewPoolImplementation = groupViewPool, map = i => i.g }, (i, view) => showGroup(i.g, view)), delegates = groupViewDelegates }; List <GroupItem <TGroup, TData, TView> > groupPool = new List <GroupItem <TGroup, TData, TView> >(); void RecycleGroup(GroupItem <TGroup, TData, TView> group) { group.DisconnectAll(); ((ReactiveCollection <TData>)group.collection).Clear(); groupPool.Add(group); } void UpdateLayoutsFromPos(int index) { groupLayout.RefillFromPos(index, grouped, LayoutBoundingsFactory); for (var i = index; i < grouped.Count; i++) { var groupView = grouped[i]; groupView.layout.SetEndShift(groupLayout.EndPointForIndex(i)); } } GroupItem <TGroup, TData, TView> CreateGroupItem(TGroup g, TData firstItem) { if (groupPool.Count > 0) { var groupItem = groupPool.TakeLast(); ((ReactiveCollection <TData>)groupItem.collection).Add(firstItem); groupItem.g = g; return(groupItem); } else { var groupColl = new ReactiveCollection <TData>(); groupColl.Add(firstItem); var groupItem = new GroupItem <TGroup, TData, TView>(); groupItem.viewLoader = new LinearViewLoader <TView, TData>(viewPool, show); groupItem.delegates = delegates; groupItem.collection = groupColl; groupItem.viewPort = viewPort; groupItem.layout = layoutFactory(groupItem.collection); groupItem.layout.UpdatePrefabSizeInfo(viewPool.sampleViewSize(firstItem)); groupItem.g = g; return(groupItem); } } groupComponents.addConnection = collection.BindCollection(ev => { if (ev.type == ReactiveCollectionEventType.Reset) { foreach (var groupView in grouped) { RecycleGroup(groupView); } grouped.Clear(); foreach (var tData in ev.newData) { var g = grouper(tData); // Lazy read group view size if (settings.forceSize == Vector2.zero) { settings.forceSize = groupViewPool.sampleViewSize(g); } if (grouped.TryFind(elem => EqualityComparer <TGroup> .Default.Equals(g, elem.g), out var coll)) { ((ReactiveCollection <TData>)coll.collection).InsertSorted(itemSort, tData); } else { var groupItem = CreateGroupItem(g, tData); groupComponents.addConnection = groupItem; grouped.InsertSorted((g1, g2) => groupSort(g1.g, g2.g), groupItem); } } foreach (var groupView in grouped) { groupView.layout.count = groupView.collection.Count; groupView.layout.RefreshSize(); } groupLayout.Refill(grouped, LayoutBoundingsFactory); for (var i = 0; i < grouped.Count; i++) { var groupView = grouped[i]; groupView.layout.SetEndShift(groupLayout.EndPointForIndex(i)); ControlItemVisibilityAndRecycle(groupView); } } else if (ev.type == ReactiveCollectionEventType.Remove) { var g = grouper(ev.oldItem); var groupView = grouped.Find(v => EqualityComparer <TGroup> .Default.Equals(v.g, g)); if (groupView == null) { throw new ZergRushException("wtf"); } var gColl = ((ReactiveCollection <TData>)groupView.collection); var index = grouped.IndexOf(groupView); var initSize = groupView.layout.size.value; gColl.Remove(ev.oldItem); if (gColl.Count == 0) { RecycleGroup(groupView); grouped.RemoveAt(index); } if (gColl.Count == 0 || initSize != groupView.layout.size.value) { UpdateLayoutsFromPos(index); } } else if (ev.type == ReactiveCollectionEventType.Insert) { var g = grouper(ev.newItem); bool needUpdatePos = false; bool groupIsNew = false; var indexOfGroup = grouped.IndexOf(v => EqualityComparer <TGroup> .Default.Equals(v.g, g)); var groupView = indexOfGroup != -1 ? grouped[indexOfGroup] : null; if (groupView == null) { groupView = CreateGroupItem(g, ev.newItem); groupComponents.addConnection = groupView; indexOfGroup = grouped.InsertSorted((g1, g2) => groupSort(g1.g, g2.g), groupView); groupView.layout.count = 1; groupView.layout.RefreshSize(); needUpdatePos = true; groupIsNew = true; } else { var initSize = groupView.layout.size.value; ((ReactiveCollection <TData>)groupView.collection).InsertSorted(itemSort, ev.newItem); if (initSize != groupView.layout.size.value) { needUpdatePos = true; } } if (needUpdatePos) { UpdateLayoutsFromPos(indexOfGroup); } if (groupIsNew) { ControlItemVisibilityAndRecycle(groupView); } } else { throw new NotImplementedException(); } }); ControlItemVisibilityAndRecycle(groupComponents); if (viewPort is ScrollRectViewPort scroll) { groupComponents.addConnection = scroll.BindToLayout(groupLayout); } groupComponents.addConnection = new AnonymousDisposable(() => { groupComponents.collection.ForEach(groupView => { groupView.DisconnectAll(); }); }); return(groupComponents); }
public void StartSystem(IObservableGroup observableGroup) { ViewPool = CreateViewPool(); OnPoolStarting(); }
public LinearViewLoader(IViewPool <TView, TData> pool, Action <TData, TView> show, Func <TView, float> unLoad = null) { this.pool = pool; this.unloadAction = unLoad; this.showAction = show; }
// Creates everithing except viewport. public static TableConnectionsAndComponents <TView, TData> CreateBasicTableComponents <TData, TView>( IReactiveCollection <TData> data, Transform parent, Action <TData, TView> show, IViewPool <TView, TData> pool = null, PrefabRef <TView> prefab = default, Func <TData, PrefabRef <TView> > prefabSelector = null, IScrollViewLayout layout = null, // Linear layout is default TableDelegates <TView> delegates = null, Func <TData, IEventStream> updater = null, PresentOptions options = PresentOptions.None ) where TView : ReusableView { var components = new TableConnectionsAndComponents <TView, TData>(); if (pool == null) { if (prefabSelector != null) { pool = new DistinctivePool <TView, TData>(parent, prefabSelector, options); } else { var actualPrefab = prefab.ExtractPrefab(parent); pool = new ViewPool <TView, TData>(parent, actualPrefab); if (options.Has(PresentOptions.UseLoadedViews)) { FillPoolWithChildrenViews(pool, parent, prefab, actualPrefab, options); } } } if (updater != null) { var showCopy = show; Action <TData, TView> showAndSubscribe = (item, view) => { showCopy(item, view); view.connections += updater(item).Subscribe(() => showCopy(item, view)); }; show = showAndSubscribe; } delegates = delegates ?? new TableDelegates <TView>(); if (delegates.onInsert != null) { show += (d, view) => { if (components.animationsEnabled) { delegates.onInsert(view); } } } ; if (options.Has(PresentOptions.PreserveSiblingOrder)) { show += (d, view) => { view.tr.SetSiblingIndex(view.indexInModel); }; } components.viewLoader = new LinearViewLoader <TView, TData>(pool, show, delegates.onRemove); components.delegates = delegates; components.collection = data; if (options.Has(PresentOptions.NeedLayout) && layout == null) { layout = LinearLayout(); } components.layout = layout; return(components); }