├── Runtime ├── MiniTween.meta ├── Utils.meta ├── Configuration.meta ├── Mvp │ ├── Animations.meta │ ├── Components.meta │ ├── Models.meta │ ├── Presenters.meta │ ├── Models │ │ ├── DataSlot.cs.meta │ │ ├── DataStack.cs.meta │ │ ├── IDataSlot.cs.meta │ │ ├── IReactive.cs.meta │ │ ├── ITrackable.cs.meta │ │ ├── DataCollection.cs.meta │ │ ├── ICloseOptions.cs.meta │ │ ├── IDataCollection.cs.meta │ │ ├── IToastManager.cs.meta │ │ ├── IToolTipManager.cs.meta │ │ ├── ReactiveModel.cs.meta │ │ ├── ToastManager.cs.meta │ │ ├── ToolTipManager.cs.meta │ │ ├── IPopupMenuProvider.cs.meta │ │ ├── PopupMenuManager.cs.meta │ │ ├── TrackableReactiveModel.cs.meta │ │ ├── IDataSlot.cs │ │ ├── ICloseOptions.cs │ │ ├── IPopupMenuProvider.cs │ │ ├── ITrackable.cs │ │ ├── IToastManager.cs │ │ ├── IDataCollection.cs │ │ ├── IReactive.cs │ │ ├── IToolTipManager.cs │ │ ├── ReactiveModel.cs │ │ ├── ToastManager.cs │ │ ├── ToolTipManager.cs │ │ ├── DataSlot.cs │ │ ├── TrackableReactiveModel.cs │ │ ├── DataCollection.cs │ │ ├── PopupMenuManager.cs │ │ └── DataStack.cs │ ├── Presenters │ │ ├── Factories.meta │ │ ├── Layout.meta │ │ ├── IBlocker.cs.meta │ │ ├── IPresenter.cs.meta │ │ ├── BindingHelper.cs.meta │ │ ├── IPresenterMap.cs.meta │ │ ├── IToolTipProvider.cs.meta │ │ ├── Layout │ │ │ ├── IMeasure.cs.meta │ │ │ ├── GridLayout.cs.meta │ │ │ ├── LayoutHelper.cs.meta │ │ │ ├── GridLayoutOptions.cs.meta │ │ │ ├── ICollectionLayout.cs.meta │ │ │ ├── ListLayoutOptions.cs.meta │ │ │ ├── CollectionLayoutOptions.cs.meta │ │ │ ├── FixedVerticalListLayout.cs.meta │ │ │ ├── FixedHorizontalListLayout.cs.meta │ │ │ ├── VariableHorizontalListLayout.cs.meta │ │ │ ├── VariableVerticalListLayout.cs.meta │ │ │ ├── IMeasure.cs │ │ │ ├── CollectionLayoutOptions.cs │ │ │ ├── ICollectionLayout.cs │ │ │ ├── ListLayoutOptions.cs │ │ │ ├── GridLayoutOptions.cs │ │ │ ├── FixedVerticalListLayout.cs │ │ │ ├── FixedHorizontalListLayout.cs │ │ │ ├── VariableVerticalListLayout.cs │ │ │ └── VariableHorizontalListLayout.cs │ │ ├── PanelPresenter.cs.meta │ │ ├── PresenterMap.cs.meta │ │ ├── UnbindPolicy.cs.meta │ │ ├── AnimatedPresenterBase.cs.meta │ │ ├── DataPresenterBase.cs.meta │ │ ├── DataSlotPresenter.cs.meta │ │ ├── DataStackPresenter.cs.meta │ │ ├── IPresenterSorting.cs.meta │ │ ├── MultipartPresenterMap.cs.meta │ │ ├── PanelCanvasPresenter.cs.meta │ │ ├── PanelPresenterBase.cs.meta │ │ ├── ToastManagerPresenter.cs.meta │ │ ├── DataCollectionPresenter.cs.meta │ │ ├── Factories │ │ │ ├── PooledFactory.cs.meta │ │ │ ├── SimpleFactory.cs.meta │ │ │ ├── IPresenterFactory.cs.meta │ │ │ ├── SingleInstanceFactory.cs.meta │ │ │ ├── PooledInjectableFactory.cs.meta │ │ │ ├── SimpleInjectableFactory.cs.meta │ │ │ ├── IPresenterFactory.cs │ │ │ ├── SimpleFactory.cs │ │ │ ├── SingleInstanceFactory.cs │ │ │ └── PooledFactory.cs │ │ ├── IPopupMenuPresenterOptions.cs.meta │ │ ├── IToastPresenterOptions.cs.meta │ │ ├── PanelCanvasGroupPresenter.cs.meta │ │ ├── PopupMenuManagerPresenter.cs.meta │ │ ├── ToolTipManagerPresenter.cs.meta │ │ ├── DataCollectionAnimatedOptions.cs.meta │ │ ├── DataCollectionAnimatedPresenter.cs.meta │ │ ├── DataCollectionSimplePresenter.cs.meta │ │ ├── DataSlotCurtainPresenterOptions.cs.meta │ │ ├── DataSlotSlidePresenterOptions.cs.meta │ │ ├── UnbindPolicy.cs │ │ ├── IBlocker.cs │ │ ├── IPresenterSorting.cs │ │ ├── IPopupMenuPresenterOptions.cs │ │ ├── IToastPresenterOptions.cs │ │ ├── PresenterUpdateKernel.cs.meta │ │ ├── IToolTipProvider.cs │ │ ├── DataSlotSlidePresenter.cs.meta │ │ ├── DataSlotCurtainPresenter.cs.meta │ │ ├── DataSlotCurtainPresenterOptions.cs │ │ ├── PanelPresenter.cs │ │ ├── DataSlotSlidePresenterOptions.cs │ │ ├── BindingHelper.cs │ │ ├── PanelCanvasGroupPresenter.cs │ │ ├── MultipartPresenterMap.cs │ │ ├── IPresenterMap.cs │ │ ├── DataCollectionAnimatedOptions.cs │ │ ├── PanelCanvasPresenter.cs │ │ ├── IPresenter.cs │ │ ├── DataStackPresenter.cs │ │ ├── PresenterMap.cs │ │ └── PresenterUpdateKernel.cs │ ├── Animations │ │ ├── IAnimator.cs.meta │ │ ├── FadeAnimation.cs.meta │ │ ├── ScaleAnimation.cs.meta │ │ ├── AnimationOptions.cs.meta │ │ ├── AnimationOptions.cs │ │ ├── FadeAnimationOptions.cs.meta │ │ ├── ScaleAnimationOptions.cs.meta │ │ ├── FadeAnimationOptions.cs │ │ ├── ScaleAnimationOptions.cs │ │ ├── IAnimator.cs │ │ ├── FadeAnimation.cs │ │ └── ScaleAnimation.cs │ └── Components │ │ ├── ButtonEx.cs.meta │ │ ├── Curtain.cs.meta │ │ ├── ViewRegion.cs.meta │ │ ├── ButtonOptions.cs.meta │ │ ├── SimpleCurtain.cs.meta │ │ ├── ButtonOptions.cs │ │ ├── FadeCurtain.cs.meta │ │ ├── SimpleCurtain.cs │ │ ├── Curtain.cs │ │ ├── ViewRegion.cs │ │ └── FadeCurtain.cs ├── Navigation.meta ├── MiniTween │ ├── ITween.cs.meta │ ├── Extensions.meta │ ├── ITweenSystem.cs.meta │ ├── MiniTweenKernel.cs.meta │ ├── MiniTweenProvider.cs.meta │ ├── Extensions │ │ ├── ImageTweenExtensions.cs.meta │ │ ├── CanvasGroupTweenExtensions.cs.meta │ │ ├── RectTransformTweenExtensions.cs.meta │ │ ├── TextMeshProTweenExtensions.cs.meta │ │ ├── CanvasGroupTweenExtensions.cs │ │ ├── ImageTweenExtensions.cs │ │ ├── TextMeshProTweenExtensions.cs │ │ └── RectTransformTweenExtensions.cs │ ├── MiniTweenOptions.asset.meta │ ├── ITweenSystem.cs │ ├── ITween.cs │ ├── MiniTweenOptions.asset │ └── MiniTweenProvider.cs ├── Utils │ ├── IFactory.cs.meta │ ├── ITickable.cs.meta │ ├── SmallSet.cs.meta │ ├── WhenAll.cs.meta │ ├── WhenBoth.cs.meta │ ├── IInjectable.cs.meta │ ├── TickerManager.cs.meta │ ├── AbstractProvider.cs.meta │ ├── DisposableExtensions.cs.meta │ ├── EventsExtensions.cs.meta │ ├── GenericDisposable.cs.meta │ ├── UnityObjectExtensions.cs.meta │ ├── ITickable.cs │ ├── DisposableExtensions.cs │ ├── UnityObjectExtensions.cs │ ├── WhenBoth.cs │ ├── WhenAll.cs │ ├── AbstractProvider.cs │ ├── GenericDisposable.cs │ ├── IInjectable.cs │ ├── TickerManager.cs │ ├── EventsExtensions.cs │ ├── IFactory.cs │ └── SmallSet.cs ├── Configuration │ ├── Loaders.meta │ ├── ConfiguratorSet.cs.meta │ ├── IConfigurator.cs.meta │ ├── MiniDiActivator.cs.meta │ ├── MiniDiContainer.cs.meta │ ├── SceneConfigurator.cs.meta │ ├── AbstractConfigurator.cs.meta │ ├── IConfiguratorLoader.cs.meta │ ├── IDependencyResolver.cs.meta │ ├── ScriptableConfigurator.cs.meta │ ├── INavigationRegistryInstaller.cs.meta │ ├── IConfigurator.cs │ ├── Loaders │ │ ├── BuildSceneConfiguratorLoader.cs.meta │ │ ├── AddressableSceneConfiguratorLoader.cs.meta │ │ ├── ResourceScriptableConfiguratorLoader.cs.meta │ │ ├── AddressableScriptableConfiguratorLoader.cs.meta │ │ ├── AssetBundleScriptableConfiguratorLoader.cs.meta │ │ ├── AddressableScriptableConfiguratorLoader.cs │ │ ├── ResourceScriptableConfiguratorLoader.cs │ │ ├── AssetBundleScriptableConfiguratorLoader.cs │ │ ├── AddressableSceneConfiguratorLoader.cs │ │ └── BuildSceneConfiguratorLoader.cs │ ├── IConfiguratorLoader.cs │ ├── INavigationRegistryInstaller.cs │ ├── AbstractConfigurator.cs │ ├── IDependencyResolver.cs │ ├── SceneConfigurator.cs │ ├── ScriptableConfigurator.cs │ └── MiniDiContainer.cs ├── Navigation │ ├── INavigable.cs.meta │ ├── NavigationBase.cs.meta │ ├── BackButtonManager.cs.meta │ ├── INavigationRegistry.cs.meta │ ├── NavigationManager.cs.meta │ ├── NavigationRegistry.cs.meta │ ├── NavigationUriResolver.cs.meta │ ├── INavigationParametersResolver.cs.meta │ ├── INavigable.cs │ ├── INavigationParametersResolver.cs │ ├── INavigationRegistry.cs │ ├── NavigationRegistry.cs │ ├── BackButtonManager.cs │ ├── NavigationBase.cs │ └── NavigationUriResolver.cs ├── Mvp.meta ├── Unity.behc.MvpToolkit.asmdef.meta └── Unity.behc.MvpToolkit.asmdef ├── AssetPackages ├── simple_game.unitypackage ├── sample_gallery.unitypackage ├── simple_game.unitypackage.meta └── sample_gallery.unitypackage.meta ├── Documentation~ ├── navigation.md ├── configuration.md ├── tween.md └── index.md ├── Samples~ ├── DataPresentersGallery │ ├── DataPresentersGallerySampleWindow.cs.meta │ ├── DataPresentersGallerySample.asmdef.meta │ ├── DataPresentersGallerySampleInstaller.cs.meta │ ├── DataPresentersGallerySample.asmdef │ ├── DataPresentersGallerySampleWindow.cs │ └── DataPresentersGallerySampleInstaller.cs └── SimpleGame │ ├── SimpleGameSample.asmdef.meta │ ├── SimpleGameSampleInstaller.cs.meta │ ├── SimpleGameSampleWindow.cs.meta │ ├── SimpleGameSample.asmdef │ ├── SimpleGameSampleWindow.cs │ └── SimpleGameSampleInstaller.cs ├── TODO.md.meta ├── CHANGELOG.md.meta ├── LICENSE.md.meta ├── README.md.meta ├── package.json.meta ├── Runtime.meta ├── AssetPackages.meta ├── TODO.md ├── README.md ├── package.json ├── LICENSE.md └── .gitignore /Runtime/MiniTween.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c1fcf4ebaf604f27b4eb642fb88cbc44 3 | timeCreated: 1621348759 -------------------------------------------------------------------------------- /Runtime/Utils.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: feb0506a70cf4841bc27fb7f72e53885 3 | timeCreated: 1620842006 -------------------------------------------------------------------------------- /Runtime/Configuration.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b87bb95ec0d4104b45d0adc34f641ed 3 | timeCreated: 1604838261 -------------------------------------------------------------------------------- /Runtime/Mvp/Animations.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c4059f5e679c47da9cef8dab96e1cc03 3 | timeCreated: 1619552372 -------------------------------------------------------------------------------- /Runtime/Mvp/Components.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 75c943fe6af2400a900867f780450a1e 3 | timeCreated: 1618935750 -------------------------------------------------------------------------------- /Runtime/Mvp/Models.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 331b81a899ac41dab6e3d3c5350f8118 3 | timeCreated: 1650744596 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b11eb38d1ba24690bb60c985b5eb47de 3 | timeCreated: 1650744605 -------------------------------------------------------------------------------- /Runtime/Navigation.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f5f0277ddc364633bc7723d95056f480 3 | timeCreated: 1604836971 -------------------------------------------------------------------------------- /Runtime/MiniTween/ITween.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 97a3dea8bf914716a209868dfc3e17bc 3 | timeCreated: 1621352269 -------------------------------------------------------------------------------- /Runtime/Utils/IFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 542f61f6c6ca447f943a963a9e971074 3 | timeCreated: 1648055146 -------------------------------------------------------------------------------- /Runtime/Utils/ITickable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 38e0c3978c8f4951b1373a913c5fa00d 3 | timeCreated: 1648988641 -------------------------------------------------------------------------------- /Runtime/Utils/SmallSet.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9c84a6d78b5d405fb177702f75b27e37 3 | timeCreated: 1646339122 -------------------------------------------------------------------------------- /Runtime/Utils/WhenAll.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 66187ff83fd04abea1467f7e25176994 3 | timeCreated: 1603901183 -------------------------------------------------------------------------------- /Runtime/Utils/WhenBoth.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83f9b18961774f5f934c3c1ad421702d 3 | timeCreated: 1603746576 -------------------------------------------------------------------------------- /Runtime/Configuration/Loaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b02ccbefeb0743689bb073f260069b32 3 | timeCreated: 1649184993 -------------------------------------------------------------------------------- /Runtime/MiniTween/Extensions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bb3bb91cb82a4242b1f37ca479029977 3 | timeCreated: 1626512851 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/DataSlot.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d59cfa947d6e4f67b24447cf386eecca 3 | timeCreated: 1603024512 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/DataStack.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d58af3dbe266483290fde0c5626dce34 3 | timeCreated: 1603911723 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/IDataSlot.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: deedeb66309f4bdb8bd3bb36e2003945 3 | timeCreated: 1645721013 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/IReactive.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b246bc5b0ab54cc4a37127fec45d9207 3 | timeCreated: 1603900647 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/ITrackable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 60f59956578143f78b696dbda3379f46 3 | timeCreated: 1603900570 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Factories.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 262dd0959af949009a9e7f1f92ab1df6 3 | timeCreated: 1650744641 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 94da6f5efb634dcd95c74b6cd9be1ff7 3 | timeCreated: 1618853981 -------------------------------------------------------------------------------- /Runtime/Navigation/INavigable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c9195f8673b1468aa82678bcbc151597 3 | timeCreated: 1604837602 -------------------------------------------------------------------------------- /Runtime/Utils/IInjectable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 626d8219edca4f7581b904674a70ffd5 3 | timeCreated: 1620231382 -------------------------------------------------------------------------------- /Runtime/Utils/TickerManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 17f8db3a8e8a4371aec31e52f70db85c 3 | timeCreated: 1648988747 -------------------------------------------------------------------------------- /Runtime/MiniTween/ITweenSystem.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4e5ba52721c8467ab6f23ae23624577d 3 | timeCreated: 1621348795 -------------------------------------------------------------------------------- /Runtime/MiniTween/MiniTweenKernel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 111894c54ac146a688805d6b59c79535 3 | timeCreated: 1621349064 -------------------------------------------------------------------------------- /Runtime/Mvp/Animations/IAnimator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ec86317aef7f49d7a83b0ce906c8f623 3 | timeCreated: 1619552721 -------------------------------------------------------------------------------- /Runtime/Mvp/Components/ButtonEx.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7a91256fb47241b7a66a1d019eb9b514 3 | timeCreated: 1620312312 -------------------------------------------------------------------------------- /Runtime/Mvp/Components/Curtain.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 351c1be7ece94e209d906a0e0a756c4f 3 | timeCreated: 1619633546 -------------------------------------------------------------------------------- /Runtime/Mvp/Components/ViewRegion.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 46a52b21ac964aaa9f99cff1c8d830ba 3 | timeCreated: 1607374708 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/DataCollection.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d0e0020c4964495bbafe9b6b89e53392 3 | timeCreated: 1604227491 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/ICloseOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 38dd1e889c4c409fb301fef7cbe7989c 3 | timeCreated: 1646065620 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/IDataCollection.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 46c6fe987f214eaabd6aa1ba3eb42252 3 | timeCreated: 1620756655 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/IToastManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b3780d49d3fe46dea527dec87e23deaa 3 | timeCreated: 1619365524 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/IToolTipManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 172548ca0d7147a0a3cecd3ba017babe 3 | timeCreated: 1619365407 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/ReactiveModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 27c8e62080854e45a43bc102734abe51 3 | timeCreated: 1603902975 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/ToastManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 733dcfeea7cc4d72a1d76f142699a359 3 | timeCreated: 1619261357 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/ToolTipManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a9effcd72ebf4a6baffdb231b6d7a9fe 3 | timeCreated: 1619270248 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/IBlocker.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6072269003d14ce78ea8c990f0a0edaa 3 | timeCreated: 1646342398 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/IPresenter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8642066b73f04f81aec44677951debd4 3 | timeCreated: 1603900750 -------------------------------------------------------------------------------- /Runtime/Navigation/NavigationBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f0e8d568a7c740bab8795220e115adea 3 | timeCreated: 1604837243 -------------------------------------------------------------------------------- /Runtime/Utils/AbstractProvider.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba22d0478f824650bffba9464e452656 3 | timeCreated: 1649527984 -------------------------------------------------------------------------------- /Runtime/Utils/DisposableExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 001c653872ae4874ab954834a9623e68 3 | timeCreated: 1645992217 -------------------------------------------------------------------------------- /Runtime/Utils/EventsExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d3fda8f4cc5b4360906468d168684c90 3 | timeCreated: 1604146210 -------------------------------------------------------------------------------- /Runtime/Utils/GenericDisposable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0d9478e8de3a4e169f7a02b811be65cf 3 | timeCreated: 1620842006 -------------------------------------------------------------------------------- /AssetPackages/simple_game.unitypackage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/behcpl/Unity-MvpToolkit/HEAD/AssetPackages/simple_game.unitypackage -------------------------------------------------------------------------------- /Runtime/Configuration/ConfiguratorSet.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2365583fb98947e1992fd8894f5398bb 3 | timeCreated: 1648985206 -------------------------------------------------------------------------------- /Runtime/Configuration/IConfigurator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 879fa5f3da5c4547aa6474794e792f1a 3 | timeCreated: 1604838295 -------------------------------------------------------------------------------- /Runtime/Configuration/MiniDiActivator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6f7f832c24cf4594aa0e87c380afe481 3 | timeCreated: 1686478146 -------------------------------------------------------------------------------- /Runtime/Configuration/MiniDiContainer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 28478446477e4cb18262e8f97aa651e6 3 | timeCreated: 1604151093 -------------------------------------------------------------------------------- /Runtime/Configuration/SceneConfigurator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 29a0d2611c7e4ab19d9108d336c6da04 3 | timeCreated: 1605114862 -------------------------------------------------------------------------------- /Runtime/MiniTween/MiniTweenProvider.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bc7f051c35b849f1992441f92cf6272b 3 | timeCreated: 1621348987 -------------------------------------------------------------------------------- /Runtime/Mvp/Animations/FadeAnimation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c1e064090d2e4cbc97a453a33eb3f84a 3 | timeCreated: 1619552864 -------------------------------------------------------------------------------- /Runtime/Mvp/Animations/ScaleAnimation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1d588d5361054253a49bae42af6565a3 3 | timeCreated: 1619555084 -------------------------------------------------------------------------------- /Runtime/Mvp/Components/ButtonOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa78e42326654c75a433d628e4ce04f3 3 | timeCreated: 1620546345 -------------------------------------------------------------------------------- /Runtime/Mvp/Components/SimpleCurtain.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d7d39c95fd56471e96c14031d5b8f01f 3 | timeCreated: 1619978863 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/IPopupMenuProvider.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 94f5d8a45a674fcf91f882eb16a4a98f 3 | timeCreated: 1622578462 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/PopupMenuManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b713bc62a5ef450b9ccbc0122b6352ee 3 | timeCreated: 1619976301 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/BindingHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: faf1878094fc4b8bae5168afd8d9cca7 3 | timeCreated: 1603904361 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/IPresenterMap.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 21010752575b4e4c933aebd312a39c2b 3 | timeCreated: 1686476468 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/IToolTipProvider.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a282d6473a84e73962ae8f10f81e566 3 | timeCreated: 1619277706 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/IMeasure.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: af771df14aa04a25be99f9acb0523316 3 | timeCreated: 1619026831 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/PanelPresenter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5458ea77408646239732eef51521552f 3 | timeCreated: 1686673729 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/PresenterMap.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 44b34e6b77cb4f1aa43e7dc0e1a018a9 3 | timeCreated: 1603024793 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/UnbindPolicy.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 86c36b526ef844139d42a3265e9516a2 3 | timeCreated: 1743412002 -------------------------------------------------------------------------------- /Runtime/Navigation/BackButtonManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0c5f02d59b744ee3a9fc767d47967d67 3 | timeCreated: 1645981300 -------------------------------------------------------------------------------- /Runtime/Navigation/INavigationRegistry.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6ef1e7fb08f84119ba852c56bbadf649 3 | timeCreated: 1648668325 -------------------------------------------------------------------------------- /Runtime/Navigation/NavigationManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 831b2bc84c59419b98ce2eb1f543a96b 3 | timeCreated: 1645981105 -------------------------------------------------------------------------------- /Runtime/Navigation/NavigationRegistry.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 34cf244e08fd4ccc85dd1bc24a7b0b38 3 | timeCreated: 1604837908 -------------------------------------------------------------------------------- /Runtime/Utils/UnityObjectExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d2bddfe99485415fafb8cfd1f3eda60f 3 | timeCreated: 1626516993 -------------------------------------------------------------------------------- /AssetPackages/sample_gallery.unitypackage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/behcpl/Unity-MvpToolkit/HEAD/AssetPackages/sample_gallery.unitypackage -------------------------------------------------------------------------------- /Runtime/Configuration/AbstractConfigurator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c0f6d5f858f2468f9f8e383785042e2b 3 | timeCreated: 1648383835 -------------------------------------------------------------------------------- /Runtime/Configuration/IConfiguratorLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d282363cf1a84dfe822de57c3ca472a7 3 | timeCreated: 1648982682 -------------------------------------------------------------------------------- /Runtime/Configuration/IDependencyResolver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6b26f12916474852a0234e7713d782a3 3 | timeCreated: 1648667762 -------------------------------------------------------------------------------- /Runtime/Configuration/ScriptableConfigurator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 80416bff36ea4a629417a3caad0babbe 3 | timeCreated: 1647368389 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/TrackableReactiveModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b1796670a94c48cca2d128cbae2bfad0 3 | timeCreated: 1603903047 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/AnimatedPresenterBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5cc0072b58eb4577a2b7c96877516130 3 | timeCreated: 1620756338 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataPresenterBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 43a419b38abe47f39aac244ada16caa4 3 | timeCreated: 1604754989 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataSlotPresenter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f7c3c4972ce84e75977e94740a30ec25 3 | timeCreated: 1603024522 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataStackPresenter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 07d69af43fbb4accad893708256e836f 3 | timeCreated: 1603911733 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/IPresenterSorting.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5b1059e57cec484584d870aec83500a0 3 | timeCreated: 1619621996 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/GridLayout.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 084e240c7658477f8ec648a65ca28212 3 | timeCreated: 1619013022 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/LayoutHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2d28a8cd14954c1a8f7f06d3b3c46a16 3 | timeCreated: 1620546761 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/MultipartPresenterMap.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ae24cb1e1f364a9abc866f307c735ac9 3 | timeCreated: 1686476705 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/PanelCanvasPresenter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: adc3eccc3e0f434c97a68c7eb88ccbe7 3 | timeCreated: 1603023811 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/PanelPresenterBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7060131427344478a022733c5a8ad095 3 | timeCreated: 1603020524 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/ToastManagerPresenter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3b9acb9b7e4f4b31a2a1b112e466d54e 3 | timeCreated: 1619261370 -------------------------------------------------------------------------------- /Runtime/Navigation/NavigationUriResolver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 51f5e2fc7ef840c6a16baac9e6823f78 3 | timeCreated: 1649276675 -------------------------------------------------------------------------------- /Runtime/Utils/ITickable.cs: -------------------------------------------------------------------------------- 1 | namespace Behc.Utils 2 | { 3 | public interface ITickable 4 | { 5 | void OnTick(); 6 | } 7 | } -------------------------------------------------------------------------------- /Runtime/MiniTween/Extensions/ImageTweenExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1fba3e1e6c094dc39fc8894e1fda9ba6 3 | timeCreated: 1626513202 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataCollectionPresenter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b0754104ba04df7a5fa568f8ca60025 3 | timeCreated: 1618328622 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Factories/PooledFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7d19d34b09bf48ddbdd037227174d6b2 3 | timeCreated: 1603987904 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Factories/SimpleFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e1117a1832bd43e4845d31e45fb76f3c 3 | timeCreated: 1603987717 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/IPopupMenuPresenterOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3470527a096b465fbc2d86266ea25e8b 3 | timeCreated: 1622887217 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/IToastPresenterOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9e7b24094df14ddcb9296179224cfb65 3 | timeCreated: 1619267766 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/GridLayoutOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9c132c28e36b44a3bc2da7465ac0e481 3 | timeCreated: 1618943036 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/ICollectionLayout.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 34995f7e7a964d3396f4aae77184f799 3 | timeCreated: 1618854031 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/ListLayoutOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 00013906887d4c5d98236a8e21da4986 3 | timeCreated: 1618854567 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/PanelCanvasGroupPresenter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 74f055a755db41d2be21a224dd1190f9 3 | timeCreated: 1603023823 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/PopupMenuManagerPresenter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b10471396bc04890aeaa53ed79006945 3 | timeCreated: 1619976321 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/ToolTipManagerPresenter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f437273e96240a9890f77191de8254c 3 | timeCreated: 1619270262 -------------------------------------------------------------------------------- /Runtime/Navigation/INavigationParametersResolver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a31103133bfe45598ca095645868f61b 3 | timeCreated: 1649269677 -------------------------------------------------------------------------------- /Runtime/Configuration/INavigationRegistryInstaller.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 23592478229f488d8b7299bf083f809c 3 | timeCreated: 1686993533 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataCollectionAnimatedOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8aefc6b7c5fa48faaf70b9908a5f315c 3 | timeCreated: 1621447289 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataCollectionAnimatedPresenter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e93d783d69c84847923ed05ae7f40911 3 | timeCreated: 1621447215 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataCollectionSimplePresenter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c1a6aacdbb7246e2828494003cf05a4c 3 | timeCreated: 1652109342 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataSlotCurtainPresenterOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 119d0f3adabc4e15b2e9b0b3321d9daf 3 | timeCreated: 1606246287 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataSlotSlidePresenterOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8a844f00232a4f5abf51fd188101b2c5 3 | timeCreated: 1606252104 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Factories/IPresenterFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 038690b95f6f4ddea676a90f1e5ce062 3 | timeCreated: 1603902285 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Factories/SingleInstanceFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6944d327292a4316ae515ada518a82b9 3 | timeCreated: 1603994573 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/CollectionLayoutOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 30576011a6364895a0b676ff7c40a4b8 3 | timeCreated: 1618854357 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/FixedVerticalListLayout.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4564fb8edd9447e1a25aa5711411f4f0 3 | timeCreated: 1618854480 -------------------------------------------------------------------------------- /Runtime/MiniTween/Extensions/CanvasGroupTweenExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 68d449562ccd440c88505078501acf13 3 | timeCreated: 1626513086 -------------------------------------------------------------------------------- /Runtime/MiniTween/Extensions/RectTransformTweenExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d5901339691943029f5b421a709ec2dc 3 | timeCreated: 1626512865 -------------------------------------------------------------------------------- /Runtime/MiniTween/Extensions/TextMeshProTweenExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e893e42e3b6f4576b635a9293d61f1b0 3 | timeCreated: 1626513515 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/IDataSlot.cs: -------------------------------------------------------------------------------- 1 | namespace Behc.Mvp.Models 2 | { 3 | public interface IDataSlot 4 | { 5 | object Data { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Factories/PooledInjectableFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5f0d1eee98c4c8686b5822a16540c04 3 | timeCreated: 1621064709 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Factories/SimpleInjectableFactory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eaa9ccf5349d451f84f78416643bf8f9 3 | timeCreated: 1620231588 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/FixedHorizontalListLayout.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 143974423789457faa9c0514a530e9e3 3 | timeCreated: 1619013148 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/VariableHorizontalListLayout.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a12949ac69b141a1b4023b13d9799874 3 | timeCreated: 1619013179 -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/VariableVerticalListLayout.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b27877f99af64a7bbf3fa7c402561afb 3 | timeCreated: 1619013161 -------------------------------------------------------------------------------- /Documentation~/navigation.md: -------------------------------------------------------------------------------- 1 | ##Navigation 2 | 3 | *(wip)* 4 | Switching between different *features* of a game 5 | 6 | Deep linking 7 | 8 | Back button / Cancel -------------------------------------------------------------------------------- /Samples~/DataPresentersGallery/DataPresentersGallerySampleWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e1d76685f68843a6b64b6a5e2ec7651a 3 | timeCreated: 1622314085 -------------------------------------------------------------------------------- /Runtime/Mvp/Models/ICloseOptions.cs: -------------------------------------------------------------------------------- 1 | namespace Behc.Mvp.Models 2 | { 3 | public interface ICloseOptions 4 | { 5 | bool CanDefaultClose { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Models/IPopupMenuProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Behc.Mvp.Models 2 | { 3 | public interface IPopupMenuProvider 4 | { 5 | object GetPopupMenu(); 6 | } 7 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Models/ITrackable.cs: -------------------------------------------------------------------------------- 1 | namespace Behc.Mvp.Models 2 | { 3 | public interface ITrackable 4 | { 5 | void Acquire(); 6 | void Release(); 7 | } 8 | } -------------------------------------------------------------------------------- /TODO.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e5b1b1e0147fc7d44a55ee77ef7c7895 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c9f49d4b201e7374a9a2552a06cbc318 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LICENSE.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 061bf81dc2338634482ac2c5bbccf80a 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 02a54927802b94b419a5e8c037c4a2af 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 20261b8046a884e4093c2f7523ebb1be 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/Mvp/Models/IToastManager.cs: -------------------------------------------------------------------------------- 1 | namespace Behc.Mvp.Models 2 | { 3 | public interface IToastManager 4 | { 5 | void AddToast(object toastData); 6 | void ClearAllToasts(); 7 | } 8 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/UnbindPolicy.cs: -------------------------------------------------------------------------------- 1 | namespace Behc.Mvp.Presenters 2 | { 3 | public enum UnbindPolicy 4 | { 5 | DEACTIVATE_GAME_OBJECT, //default option 6 | KEEP_UNCHANGED, 7 | } 8 | } -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9e72b4659cd7d204b800aba287698ee7 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/IBlocker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Behc.Mvp.Presenters 4 | { 5 | public interface IBlocker 6 | { 7 | event Action OnBlockingStatusChange; 8 | } 9 | } -------------------------------------------------------------------------------- /AssetPackages.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 30240f96ee9068140947333d8c2c859f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Mvp.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f2315c35b79465f4a890793f92974f93 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/IPresenterSorting.cs: -------------------------------------------------------------------------------- 1 | namespace Behc.Mvp.Presenters 2 | { 3 | public interface IPresenterSorting 4 | { 5 | void SetSortingOrder(int baseSortingOrder, int sortingLayerId); 6 | } 7 | } -------------------------------------------------------------------------------- /AssetPackages/simple_game.unitypackage.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 221dc61e04343fe429bce877654bfdc4 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/Utils/DisposableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Behc.Utils 4 | { 5 | public static class DisposableExtensions 6 | { 7 | public static void KeepForever(this IDisposable _) {} 8 | } 9 | } -------------------------------------------------------------------------------- /AssetPackages/sample_gallery.unitypackage.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 57fe149359fa18844aac7f2225a13c18 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/Mvp/Models/IDataCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Behc.Mvp.Models 4 | { 5 | public interface IDataCollection 6 | { 7 | IReadOnlyCollection Data { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/IPopupMenuPresenterOptions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Mvp.Presenters 4 | { 5 | public interface IPopupMenuPresenterOptions 6 | { 7 | Vector2 Separation { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /Runtime/Unity.behc.MvpToolkit.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 99abd855f049e6f4498f0cdb860d3ca7 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/SimpleGame/SimpleGameSample.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4509db915c730604db1fd020eb72edce 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/Configuration/IConfigurator.cs: -------------------------------------------------------------------------------- 1 | namespace Behc.Configuration 2 | { 3 | public interface IConfigurator 4 | { 5 | void Load(IDependencyResolver resolver); 6 | void Unload(IDependencyResolver resolver); 7 | } 8 | } -------------------------------------------------------------------------------- /Runtime/MiniTween/MiniTweenOptions.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f66f8dba85acd614d91710862211a522 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/DataPresentersGallery/DataPresentersGallerySample.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5c508fe8a4092aa408e78bca8cb6a119 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/Mvp/Models/IReactive.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | 4 | namespace Behc.Mvp.Models 5 | { 6 | public interface IReactive 7 | { 8 | [MustUseReturnValue] 9 | IDisposable Subscribe(Action action); 10 | } 11 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/IToastPresenterOptions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Mvp.Presenters 4 | { 5 | public interface IToastPresenterOptions 6 | { 7 | float LifeTime { get; } 8 | Vector2 Velocity { get; } 9 | } 10 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/IMeasure.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Mvp.Presenters.Layout 4 | { 5 | public interface IMeasure 6 | { 7 | void Prepare(Vector2 size); 8 | Vector2 MeasureModel(object model); 9 | } 10 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/CollectionLayoutOptions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Mvp.Presenters.Layout 4 | { 5 | public abstract class CollectionLayoutOptions : ScriptableObject 6 | { 7 | public abstract ICollectionLayout CreateLayout(); 8 | } 9 | } -------------------------------------------------------------------------------- /Runtime/MiniTween/ITweenSystem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Behc.MiniTween 5 | { 6 | public interface ITweenSystem 7 | { 8 | ITween Animate(object owner, Action setter, Vector4 from, Vector4 to, float duration); 9 | } 10 | } -------------------------------------------------------------------------------- /Runtime/Navigation/INavigable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Behc.Navigation 4 | { 5 | public interface INavigable 6 | { 7 | void Start(); 8 | void Restart(object parameters); 9 | void Stop(); 10 | 11 | void LongDispose(Action onComplete); 12 | } 13 | } -------------------------------------------------------------------------------- /Runtime/Navigation/INavigationParametersResolver.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Behc.Navigation 4 | { 5 | public interface INavigationParametersResolver 6 | { 7 | object FromUri(IReadOnlyList uriPath, IReadOnlyDictionary uriParameters); 8 | } 9 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Models/IToolTipManager.cs: -------------------------------------------------------------------------------- 1 | namespace Behc.Mvp.Models 2 | { 3 | public interface IToolTipManager 4 | { 5 | object CurrentToolTip { get; } 6 | bool IsSuppressed { get; } 7 | void Suppress(object owner); 8 | void ReleaseSuppression(object owner); 9 | } 10 | } -------------------------------------------------------------------------------- /Samples~/SimpleGame/SimpleGameSampleInstaller.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b80c8fba7f754ed438be45499ef6768d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/SimpleGame/SimpleGameSampleWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5a4510a42b450e14caa163d4c3bfc2fc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/PresenterUpdateKernel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d2ecbd0723e345129de6e1ddb712b58e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 1000 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Configuration/Loaders/BuildSceneConfiguratorLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 04d3c0bd6b31c1945a67d6b50ac4507c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Factories/IPresenterFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Behc.Mvp.Presenters.Factories 5 | { 6 | public interface IPresenterFactory : IDisposable 7 | { 8 | IPresenter CreatePresenter(RectTransform parentTransform); 9 | void DestroyPresenter(IPresenter presenter); 10 | } 11 | } -------------------------------------------------------------------------------- /Runtime/Configuration/Loaders/AddressableSceneConfiguratorLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 04d4b6fdb31fcc642ab4eb15eed9a65a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Configuration/Loaders/ResourceScriptableConfiguratorLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 47fdd78e226916f489c781132f22a640 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Configuration/Loaders/AddressableScriptableConfiguratorLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6e4c2335b321bab4fa133f612202e0a1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Configuration/Loaders/AssetBundleScriptableConfiguratorLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 684765553e2344c4892d7691c41a471e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/DataPresentersGallery/DataPresentersGallerySampleInstaller.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e3a1292e6d745ec46bc1a419f658b88f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Mvp/Components/ButtonOptions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Mvp.Components 4 | { 5 | [CreateAssetMenu(fileName = "ButtonOptions", menuName = "MvpToolkit/ButtonOptions", order = 600)] 6 | public class ButtonOptions : ScriptableObject 7 | { 8 | public float HoverDelay = 0.2f; 9 | public float LongPressDuration = 0.5f; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Runtime/Navigation/INavigationRegistry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Behc.Utils; 3 | using JetBrains.Annotations; 4 | 5 | namespace Behc.Navigation 6 | { 7 | public interface INavigationRegistry : IFactory 8 | { 9 | [MustUseReturnValue] 10 | IDisposable Register([NotNull] string name, [NotNull] IFactory navigableFactory); 11 | } 12 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Animations/AnimationOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 12653c2165f14752881b2d01b7680edf 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - TweenProvider: {fileID: 11400000, guid: f66f8dba85acd614d91710862211a522, type: 2} 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Runtime/Mvp/Animations/AnimationOptions.cs: -------------------------------------------------------------------------------- 1 | using Behc.MiniTween; 2 | using Behc.Utils; 3 | using UnityEngine; 4 | 5 | namespace Behc.Mvp.Animations 6 | { 7 | public abstract class AnimationOptions : ScriptableObject 8 | { 9 | public AbstractProvider TweenProvider; 10 | 11 | public abstract IAnimator CreateAnimator(RectTransform transform, CanvasGroup canvasGroup); 12 | } 13 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Animations/FadeAnimationOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ada80494a9e04f08a30b613dfbabe1d1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - TweenProvider: {fileID: 11400000, guid: f66f8dba85acd614d91710862211a522, type: 2} 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Runtime/Mvp/Animations/ScaleAnimationOptions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9dd2d61a68b44a3e8ee675261cbcecc2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - TweenProvider: {fileID: 11400000, guid: f66f8dba85acd614d91710862211a522, type: 2} 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Documentation~/configuration.md: -------------------------------------------------------------------------------- 1 | ## Configuration 2 | 3 | *(wip)* 4 | Configuration elements: 5 | - Root element on scene (additive loading) 6 | - ScriptableObject (for addressables) 7 | 8 | MiniDiContainer - simplistic dependency injection system 9 | 10 | Use pure di (by constructor) where possible, and IInjectable for MonoBehaviours 11 | Get dependencies from context or resolve from container, but only inside configuration phase 12 | -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/IToolTipProvider.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Mvp.Presenters 4 | { 5 | public interface IToolTipProvider 6 | { 7 | // This method will be called every frame, make sure it returns cached model 8 | // hit GameObject is the first one from RaycastAll results, 9 | // only first IPresenter will be queried about IToolTipProvider 10 | object GetToolTip(GameObject hit); 11 | } 12 | } -------------------------------------------------------------------------------- /Runtime/MiniTween/ITween.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Behc.MiniTween 5 | { 6 | public interface ITween 7 | { 8 | void Kill(); 9 | void Complete(); 10 | void SetCurrentTime(float time); 11 | 12 | void SetId(string id); 13 | void SetUpdateCallback(Action onUpdate); 14 | void SetCompleteCallback(Action onComplete); 15 | void SetEase(AnimationCurve curve); 16 | } 17 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataSlotSlidePresenter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1086daf6e599eea43a5d0c300e951ab9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - _options: {instanceID: 0} 8 | - _tweenProvider: {fileID: 11400000, guid: f66f8dba85acd614d91710862211a522, type: 2} 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataSlotCurtainPresenter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c70eff5f84b64beb8cbffd81bb5fe1d2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - _curtain: {instanceID: 0} 8 | - _options: {instanceID: 0} 9 | - _tweenProvider: {fileID: 11400000, guid: f66f8dba85acd614d91710862211a522, type: 2} 10 | executionOrder: 0 11 | icon: {instanceID: 0} 12 | userData: 13 | assetBundleName: 14 | assetBundleVariant: 15 | -------------------------------------------------------------------------------- /Runtime/MiniTween/MiniTweenOptions.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 11500000, guid: bc7f051c35b849f1992441f92cf6272b, type: 3} 13 | m_Name: MiniTweenOptions 14 | m_EditorClassIdentifier: 15 | UnscaledTime: 0 16 | -------------------------------------------------------------------------------- /Runtime/Mvp/Components/FadeCurtain.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8473e7c070f64be6b8590dd35be5f901 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - _tweenProvider: {fileID: 11400000, guid: f66f8dba85acd614d91710862211a522, type: 2} 8 | - _mainGroup: {instanceID: 0} 9 | - _mainCanvas: {instanceID: 0} 10 | - _auxGroup: {instanceID: 0} 11 | - _auxCanvas: {instanceID: 0} 12 | executionOrder: 0 13 | icon: {instanceID: 0} 14 | userData: 15 | assetBundleName: 16 | assetBundleVariant: 17 | -------------------------------------------------------------------------------- /Runtime/MiniTween/Extensions/CanvasGroupTweenExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.MiniTween.Extensions 4 | { 5 | public static class CanvasGroupTweenExtensions 6 | { 7 | public static ITween AnimateAlpha(this CanvasGroup cg, ITweenSystem system, float to, float duration) 8 | { 9 | return system.Animate(cg, SetAlpha, new Vector4(0, 0, 0, cg.alpha), new Vector4(0, 0, 0, to), duration); 10 | } 11 | 12 | private static void SetAlpha(object cg, Vector4 value) => ((CanvasGroup) cg).alpha = value.w; 13 | } 14 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Animations/FadeAnimationOptions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Mvp.Animations 4 | { 5 | [CreateAssetMenu(fileName = "FadeAnimation", menuName = "MvpToolkit/FadeAnimation", order = 200)] 6 | public class FadeAnimationOptions : AnimationOptions 7 | { 8 | public float ShowDuration = 0.2f; 9 | public float HideDuration = 0.2f; 10 | 11 | public override IAnimator CreateAnimator(RectTransform transform, CanvasGroup canvasGroup) 12 | { 13 | return new FadeAnimation(this, canvasGroup); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataSlotCurtainPresenterOptions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Mvp.Presenters 4 | { 5 | [CreateAssetMenu(fileName = "DataSlotCurtainOptions", menuName = "MvpToolkit/DataSlotCurtainOptions", order = 100)] 6 | public class DataSlotCurtainPresenterOptions : ScriptableObject 7 | { 8 | public float ShowDuration = 0.2f; 9 | public float HideDuration = 0.2f; 10 | public AnimationCurve ShowCurve = AnimationCurve.EaseInOut(0, 0, 1, 1); 11 | public AnimationCurve HideCurve = AnimationCurve.EaseInOut(0, 0, 1, 1); 12 | } 13 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Models/ReactiveModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Behc.Utils; 3 | using JetBrains.Annotations; 4 | 5 | namespace Behc.Mvp.Models 6 | { 7 | public class ReactiveModel : IReactive 8 | { 9 | private event Action _onChange; 10 | 11 | [MustUseReturnValue] 12 | public IDisposable Subscribe(Action action) 13 | { 14 | _onChange += action; 15 | 16 | return new GenericDisposable(() => _onChange -= action); 17 | } 18 | 19 | protected void NotifyChanges() 20 | { 21 | _onChange?.Invoke(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/PanelPresenter.cs: -------------------------------------------------------------------------------- 1 | namespace Behc.Mvp.Presenters 2 | { 3 | public class PanelPresenter : PanelPresenterBase where T : class 4 | { 5 | public sealed override void Initialize(IPresenterMap presenterMap, PresenterUpdateKernel kernel) 6 | { 7 | base.Initialize(presenterMap, kernel); 8 | } 9 | 10 | public sealed override void Activate() 11 | { 12 | base.Activate(); 13 | } 14 | 15 | public sealed override void Deactivate() 16 | { 17 | base.Deactivate(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Runtime/Utils/UnityObjectExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Utils 4 | { 5 | public static class UnityObjectExtensions 6 | { 7 | // bypass heavy unity check, with proper lifetime control of scripts, there is no need for it 8 | public static bool IsNull(this Object unityObject) 9 | { 10 | object obj = unityObject; 11 | return obj == null; 12 | } 13 | 14 | public static bool IsNotNull(this Object unityObject) 15 | { 16 | object obj = unityObject; 17 | return obj != null; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Runtime/Configuration/IConfiguratorLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Behc.Configuration 4 | { 5 | public enum ConfiguratorStatus 6 | { 7 | UNLOADED, 8 | LOADED, 9 | UNLOADING, 10 | LOADING, 11 | DOWNLOADING, 12 | //TODO: error status 13 | } 14 | 15 | public interface IConfiguratorLoader 16 | { 17 | ConfiguratorStatus Status { get; } 18 | float Progress { get; } 19 | 20 | void Load(IDependencyResolver resolver, Action onComplete); 21 | void Unload(IDependencyResolver resolver, Action onComplete); 22 | } 23 | } -------------------------------------------------------------------------------- /Samples~/SimpleGame/SimpleGameSample.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SimpleGameSample", 3 | "rootNamespace": "", 4 | "references": [], 5 | "includePlatforms": [ 6 | "Editor" 7 | ], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [], 14 | "versionDefines": [ 15 | { 16 | "name": "com.unity.textmeshpro", 17 | "expression": "1.0.0", 18 | "define": "SAMPLE_TEXTMESHPRO_PRESENT" 19 | } 20 | ], 21 | "noEngineReferences": false 22 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/ICollectionLayout.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Behc.Mvp.Presenters.Layout 5 | { 6 | public interface ICollectionLayout 7 | { 8 | void SetContentSize(float width, float height); 9 | 10 | Rect EvaluateRect(int index, IReadOnlyList rects, Vector2 requestedSize, float requestedGap); 11 | Vector2 GetApproximatedContentSize(Vector2 defaultSize, int itemsCount); 12 | Vector2 GetOptimalContentSize(Vector2 defaultSize, IReadOnlyList rects); 13 | 14 | bool RebuildRequired(bool widthChanged, bool heightChanged); 15 | } 16 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Components/SimpleCurtain.cs: -------------------------------------------------------------------------------- 1 | namespace Behc.Mvp.Components 2 | { 3 | public class SimpleCurtain : Curtain 4 | { 5 | public override void Setup(bool visible, int order) 6 | { 7 | gameObject.SetActive(visible); 8 | } 9 | 10 | public override void Show(int order) 11 | { 12 | gameObject.SetActive(true); 13 | } 14 | 15 | public override void Switch(int newOrder, int previousOrder) 16 | { 17 | gameObject.SetActive(true); 18 | } 19 | 20 | public override void Hide() 21 | { 22 | gameObject.SetActive(false); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Samples~/DataPresentersGallery/DataPresentersGallerySample.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DataPresentersGallerySample", 3 | "rootNamespace": "", 4 | "references": [], 5 | "includePlatforms": [ 6 | "Editor" 7 | ], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [], 14 | "versionDefines": [ 15 | { 16 | "name": "com.unity.textmeshpro", 17 | "expression": "1.0.0", 18 | "define": "SAMPLE_TEXTMESHPRO_PRESENT" 19 | } 20 | ], 21 | "noEngineReferences": false 22 | } -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | (in no particular order) 4 | 5 | * Documentation, more documentation and even more documentation! 6 | * Cleanup and optimize DataCollectionAnimatedPresenter 7 | * Add grid support for DataCollectionAnimatedPresenter (nicer animations of moving elements) 8 | * Add new animation type for resizing (not scaling) RectTransforms, can be useful for popup menu or drop down boxes 9 | * Add more transition options for sliding mode (move only new/old presenter) 10 | * Add animation support for ToolTipManager 11 | * Move code dependent on raw mouse/pointer input into abstracted service 12 | 13 | Planned for v2.0 14 | 15 | * UiToolkit support (as separate package or interchangeable components) -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataSlotSlidePresenterOptions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Mvp.Presenters 4 | { 5 | [CreateAssetMenu(fileName = "DataSlotSlidePresenterOptions", menuName = "MvpToolkit/DataSlotSlideOptions", order = 100)] 6 | public class DataSlotSlidePresenterOptions : ScriptableObject 7 | { 8 | public enum DirectionType 9 | { 10 | LEFT_RIGHT, 11 | RIGHT_LEFT, 12 | TOP_DOWN, 13 | BOTTOM_UP, 14 | } 15 | 16 | public DirectionType Direction; 17 | public float TransitionDuration = 0.2f; 18 | public AnimationCurve TransitionCurve = AnimationCurve.EaseInOut(0, 0, 1, 1); 19 | } 20 | } -------------------------------------------------------------------------------- /Runtime/Configuration/INavigationRegistryInstaller.cs: -------------------------------------------------------------------------------- 1 | using Behc.Navigation; 2 | 3 | namespace Behc.Configuration 4 | { 5 | public interface INavigationRegistryInstaller 6 | { 7 | public void Install(IDependencyResolver resolver, INavigationRegistry navigationRegistry); 8 | } 9 | 10 | public static class NavigationRegistryExtensions 11 | { 12 | public static INavigationRegistry Add(this INavigationRegistry navigationRegistry, IDependencyResolver resolver) where T : INavigationRegistryInstaller, new() 13 | { 14 | T installer = new T(); 15 | installer.Install(resolver, navigationRegistry); 16 | return navigationRegistry; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Models/ToastManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Behc.Mvp.Models 4 | { 5 | public class ToastManager : ReactiveModel, IToastManager 6 | { 7 | public IReadOnlyList Toasts => _toasts; 8 | 9 | private readonly List _toasts = new List(16); 10 | 11 | public void AddToast(object toastData) 12 | { 13 | _toasts.Add(toastData); 14 | NotifyChanges(); 15 | } 16 | 17 | public void FinishToast(object toastData) 18 | { 19 | _toasts.Remove(toastData); 20 | NotifyChanges(); 21 | } 22 | 23 | public void ClearAllToasts() 24 | { 25 | _toasts.Clear(); 26 | NotifyChanges(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unity-MvpToolkit 2 | Lean architecture for rapid UI heavy games setup for Unity. 3 | It is based around [Model-View-Presenter](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter) 4 | pattern with optional auxiliary components for typical tasks like 5 | scene configuration or dependency management. 6 | 7 | [Documentation](./Documentation~/index.md) 8 | 9 | ### Installation 10 | 11 | MvpToolkit is available as a package and can be installed using Package Manager with 12 | direct git link or using OpenUPM. The latter is preferred as it enabled easy version updates. 13 | 14 | In order to use OpenUPM, [scoped registry](https://docs.unity3d.com/2020.3/Documentation/Manual/upm-scoped.html) 15 | must be added to Package Manager Project Settings: *https://package.openupm.com* with *com.behc* scope. 16 | -------------------------------------------------------------------------------- /Runtime/Utils/WhenBoth.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Behc.Utils 4 | { 5 | public struct WhenBoth 6 | { 7 | private bool _first; 8 | private bool _second; 9 | private Action _onComplete; 10 | 11 | public void Setup(Action onComplete) 12 | { 13 | _onComplete = onComplete; 14 | } 15 | 16 | public void CompletedFirst() 17 | { 18 | _first = true; 19 | if (_second) 20 | { 21 | _onComplete?.Invoke(); 22 | _onComplete = null; 23 | } 24 | } 25 | 26 | public void CompletedSecond() 27 | { 28 | _second = true; 29 | if (_first) 30 | { 31 | _onComplete?.Invoke(); 32 | _onComplete = null; 33 | } 34 | } 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/BindingHelper.cs: -------------------------------------------------------------------------------- 1 | using Behc.Mvp.Models; 2 | 3 | namespace Behc.Mvp.Presenters 4 | { 5 | public static class BindingHelper 6 | { 7 | public static void Bind(object model, IPresenter presenter, IPresenter parent, bool prepareForAnimation) 8 | { 9 | if (presenter == null) 10 | return; 11 | 12 | if(model is ITrackable trackable) 13 | trackable.Acquire(); 14 | 15 | presenter.Bind(model, parent, prepareForAnimation); 16 | } 17 | 18 | public static void Unbind(object model, IPresenter presenter) 19 | { 20 | if (presenter == null) 21 | return; 22 | 23 | if(model is ITrackable trackable) 24 | trackable.Release(); 25 | 26 | presenter.Unbind(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Models/ToolTipManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Behc.Mvp.Models 4 | { 5 | public class ToolTipManager : ReactiveModel, IToolTipManager 6 | { 7 | public object CurrentToolTip { get; private set; } 8 | public bool IsSuppressed => _suppressedBy.Count > 0; 9 | 10 | private readonly HashSet _suppressedBy = new HashSet(); 11 | 12 | public void Suppress(object owner) 13 | { 14 | _suppressedBy.Add(owner); 15 | } 16 | 17 | public void ReleaseSuppression(object owner) 18 | { 19 | _suppressedBy.Remove(owner); 20 | } 21 | 22 | public void SetCurrentToolTip(object toolTip) 23 | { 24 | if (CurrentToolTip == toolTip) 25 | return; 26 | 27 | CurrentToolTip = toolTip; 28 | NotifyChanges(); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/PanelCanvasGroupPresenter.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Mvp.Presenters 4 | { 5 | public class PanelCanvasGroupPresenter : PanelPresenterBase where T : class 6 | { 7 | #pragma warning disable CS0649 8 | [SerializeField] protected CanvasGroup _canvasGroup; 9 | #pragma warning restore CS0649 10 | 11 | public sealed override void Initialize(IPresenterMap presenterMap, PresenterUpdateKernel kernel) 12 | { 13 | base.Initialize(presenterMap, kernel); 14 | 15 | _canvasGroup.interactable = false; 16 | } 17 | 18 | public sealed override void Activate() 19 | { 20 | base.Activate(); 21 | 22 | _canvasGroup.interactable = true; 23 | } 24 | 25 | public sealed override void Deactivate() 26 | { 27 | _canvasGroup.interactable = false; 28 | 29 | base.Deactivate(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Animations/ScaleAnimationOptions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Mvp.Animations 4 | { 5 | [CreateAssetMenu(fileName = "ScaleAnimation", menuName = "MvpToolkit/ScaleAnimation", order = 200)] 6 | public class ScaleAnimationOptions : AnimationOptions 7 | { 8 | public float ShowScaleStart = 0.5f; 9 | public AnimationCurve ShowScaleCurve = AnimationCurve.Linear(0, 0, 1, 1); 10 | public float ShowAlphaStart = 1.0f; 11 | public float ShowDuration = 0.2f; //[s] 12 | 13 | public float HideScaleEnd = 1.5f; 14 | public AnimationCurve HideScaleCurve = AnimationCurve.Linear(0, 0, 1, 1); 15 | public float HideAlphaEnd = 1.0f; 16 | public float HideDuration = 0.2f; //[s] 17 | 18 | public override IAnimator CreateAnimator(RectTransform transform, CanvasGroup canvasGroup) 19 | { 20 | return new ScaleAnimation(this, transform, canvasGroup); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Runtime/Utils/WhenAll.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Behc.Utils 4 | { 5 | public class WhenAll 6 | { 7 | private bool[] _conditions; 8 | private Action _onComplete; 9 | 10 | public void Setup(Action onComplete, int conditionsCount) 11 | { 12 | _onComplete = onComplete; 13 | 14 | if (_conditions == null || _conditions.Length != conditionsCount) 15 | _conditions = new bool[conditionsCount]; 16 | 17 | for (int i = 0; i < _conditions.Length; i++) 18 | _conditions[i] = false; 19 | } 20 | 21 | public void Completed(int index) 22 | { 23 | _conditions[index] = true; 24 | 25 | for (int i = 0; i < _conditions.Length; i++) 26 | { 27 | if (!_conditions[i]) 28 | return; 29 | } 30 | 31 | _onComplete?.Invoke(); 32 | _onComplete = null; 33 | } 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.behc.mvptoolkit", 3 | "version": "0.14.2", 4 | "displayName": "MvpToolkit", 5 | "description": "Lean architecture for rapid UI/Game setup", 6 | "unity": "2019.4", 7 | "dependencies": {}, 8 | "keywords": [ 9 | "architecture", 10 | "ugui", 11 | "mvp" 12 | ], 13 | "author": { 14 | "name": "BEHC Bartosz Czuba", 15 | "email": "bartosz.czuba@behc.pl", 16 | "url": "https://github.com/behcpl/Unity-MvpToolkit" 17 | }, 18 | "samples": [ 19 | { 20 | "displayName": "Data Presenters Gallery", 21 | "description": "Showcase of all data presenters (like slot or collection) with multiple animation options. Requires TextMesh Pro essentials.", 22 | "path": "Samples~/DataPresentersGallery" 23 | }, { 24 | "displayName": "Simple Game", 25 | "description": "Very basic game UI setup, with navigation between multiple scenes. Requires TextMesh Pro essentials.", 26 | "path": "Samples~/SimpleGame" 27 | } 28 | ] 29 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Models/DataSlot.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace Behc.Mvp.Models 4 | { 5 | public class DataSlot : ReactiveModel, IDataSlot 6 | { 7 | private object _data; 8 | 9 | [CanBeNull] 10 | public object Data 11 | { 12 | get => _data; 13 | set 14 | { 15 | if (ReferenceEquals(_data, value)) 16 | return; 17 | 18 | _data = value; 19 | NotifyChanges(); 20 | } 21 | } 22 | } 23 | 24 | public class DataSlot : ReactiveModel, IDataSlot where T : class 25 | { 26 | private T _data; 27 | 28 | object IDataSlot.Data => _data; 29 | 30 | [CanBeNull] 31 | public T Data 32 | { 33 | get => _data; 34 | set 35 | { 36 | if (ReferenceEquals(_data, value)) 37 | return; 38 | 39 | _data = value; 40 | NotifyChanges(); 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Runtime/Utils/AbstractProvider.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Utils 4 | { 5 | // [CreateAssetMenu(fileName = "AbstractProvider", menuName = "Game/Service/Provider", order = 0)] 6 | public abstract class AbstractProvider : ScriptableObject 7 | { 8 | public abstract TService GetInstance(); 9 | 10 | #if UNITY_EDITOR 11 | private void OnEnable() 12 | { 13 | UnityEditor.EditorApplication.playModeStateChanged += EditorApplicationOnplayModeStateChanged; 14 | } 15 | 16 | private void OnDisable() 17 | { 18 | UnityEditor.EditorApplication.playModeStateChanged -= EditorApplicationOnplayModeStateChanged; 19 | } 20 | 21 | private void EditorApplicationOnplayModeStateChanged(UnityEditor.PlayModeStateChange obj) 22 | { 23 | if (obj == UnityEditor.PlayModeStateChange.EnteredEditMode) 24 | { 25 | OnEditorReset(); 26 | } 27 | } 28 | 29 | protected virtual void OnEditorReset() { } 30 | #endif 31 | } 32 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Animations/IAnimator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Behc.Mvp.Animations 4 | { 5 | public interface IAnimator 6 | { 7 | bool IsAnimating { get; } 8 | 9 | void Setup(bool prepareForAnimation); 10 | void AnimateShow(float startTime, Action onFinish); 11 | void AnimateHide(float startTime, Action onFinish); 12 | void AbortAnimations(); 13 | } 14 | 15 | public static class AnimatorExtensions 16 | { 17 | public static void AnimateShowOrFinish(this IAnimator animator, float startTime, Action onFinish) 18 | { 19 | if(animator != null) 20 | animator.AnimateShow(startTime, onFinish); 21 | else 22 | onFinish?.Invoke(); 23 | } 24 | 25 | public static void AnimateHideOrFinish(this IAnimator animator, float startTime, Action onFinish) 26 | { 27 | if(animator != null) 28 | animator.AnimateHide(startTime, onFinish); 29 | else 30 | onFinish?.Invoke(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Runtime/Utils/GenericDisposable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Behc.Utils 5 | { 6 | public class GenericDisposable : IDisposable 7 | { 8 | public static GenericDisposable Noop = new GenericDisposable(null); 9 | 10 | private readonly Action _disposeAction; 11 | 12 | public GenericDisposable(Action disposeAction) 13 | { 14 | _disposeAction = disposeAction; 15 | } 16 | 17 | public GenericDisposable(IEnumerable disposables, Action disposeBefore = null, Action disposeAfter = null) 18 | { 19 | _disposeAction = () => 20 | { 21 | disposeBefore?.Invoke(); 22 | 23 | foreach (IDisposable disposable in disposables) 24 | { 25 | disposable.Dispose(); 26 | } 27 | 28 | disposeAfter?.Invoke(); 29 | }; 30 | } 31 | 32 | public void Dispose() 33 | { 34 | _disposeAction?.Invoke(); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Runtime/Unity.behc.MvpToolkit.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "behc.MvpToolkit", 3 | "rootNamespace": "Behc", 4 | "references": [ 5 | "Unity.InputSystem", 6 | "Unity.TextMeshPro", 7 | "Unity.ResourceManager", 8 | "Unity.Addressables" 9 | ], 10 | "includePlatforms": [], 11 | "excludePlatforms": [], 12 | "allowUnsafeCode": false, 13 | "overrideReferences": false, 14 | "precompiledReferences": [], 15 | "autoReferenced": true, 16 | "defineConstraints": [], 17 | "versionDefines": [ 18 | { 19 | "name": "com.unity.inputsystem", 20 | "expression": "", 21 | "define": "BEHC_MVPTOOLKIT_INPUTSYSTEM" 22 | }, 23 | { 24 | "name": "com.unity.textmeshpro", 25 | "expression": "1.0.0", 26 | "define": "BEHC_MVPTOOLKIT_TEXTMESHPRO" 27 | }, 28 | { 29 | "name": "com.unity.addressables", 30 | "expression": "", 31 | "define": "BEHC_MVPTOOLKIT_ADDRESSABLES" 32 | } 33 | ], 34 | "noEngineReferences": false 35 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/ListLayoutOptions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Mvp.Presenters.Layout 4 | { 5 | [CreateAssetMenu(fileName = "ListLayoutOptions", menuName = "MvpToolkit/ListLayoutOptions", order = 300)] 6 | public class ListLayoutOptions : CollectionLayoutOptions 7 | { 8 | public enum DirectionType 9 | { 10 | VERTICAL, 11 | HORIZONTAL, 12 | } 13 | 14 | public RectOffset Padding = new RectOffset(); 15 | public DirectionType Direction; 16 | 17 | public float GapSize = 10; 18 | public float ElementSize = 100; 19 | 20 | public bool FixedElementSize = true; 21 | 22 | public override ICollectionLayout CreateLayout() 23 | { 24 | return Direction == DirectionType.HORIZONTAL ? 25 | FixedElementSize ? (ICollectionLayout) new FixedHorizontalListLayout(this) : new VariableHorizontalListLayout(this) : 26 | FixedElementSize ? (ICollectionLayout) new FixedVerticalListLayout(this) : new VariableVerticalListLayout(this); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Bartosz Czuba 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Runtime/MiniTween/MiniTweenProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Behc.Utils; 3 | using UnityEngine; 4 | 5 | namespace Behc.MiniTween 6 | { 7 | [CreateAssetMenu(fileName = "MiniTweenOptions", menuName = "MvpToolkit/MiniTween", order = 500)] 8 | public class MiniTweenProvider : AbstractProvider 9 | { 10 | public bool UnscaledTime; 11 | public bool DisablePooling; 12 | 13 | [NonSerialized] private MiniTweenKernel _kernel; 14 | 15 | public override ITweenSystem GetInstance() 16 | { 17 | if (_kernel.IsNull()) 18 | { 19 | #if BEHC_MVPTOOLKIT_VERBOSE 20 | Debug.LogWarning("Creating new MiniTween kernel!"); 21 | #endif 22 | GameObject go = new GameObject("MiniTween"); 23 | _kernel = go.AddComponent(); 24 | _kernel.Initialize(this); 25 | DontDestroyOnLoad(go); 26 | } 27 | 28 | return _kernel; 29 | } 30 | 31 | #if UNITY_EDITOR 32 | protected override void OnEditorReset() 33 | { 34 | _kernel = null; 35 | } 36 | #endif 37 | } 38 | } -------------------------------------------------------------------------------- /Runtime/Configuration/AbstractConfigurator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using JetBrains.Annotations; 4 | 5 | namespace Behc.Configuration 6 | { 7 | public abstract class AbstractConfigurator : IConfigurator 8 | { 9 | private List _disposables; 10 | 11 | void IConfigurator.Load(IDependencyResolver resolver) 12 | { 13 | MiniDiActivator.CallMethod(resolver, this, "OnLoad"); 14 | } 15 | 16 | void IConfigurator.Unload(IDependencyResolver resolver) 17 | { 18 | MiniDiActivator.CallMethod(resolver, this, "OnUnload"); 19 | 20 | if (_disposables != null) 21 | { 22 | foreach (IDisposable disposable in _disposables) 23 | { 24 | disposable.Dispose(); 25 | } 26 | 27 | _disposables.Clear(); 28 | _disposables = null; 29 | } 30 | } 31 | 32 | protected void DisposeOnUnload([NotNull] IDisposable disposable) 33 | { 34 | _disposables ??= new List(); 35 | _disposables.Add(disposable); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/MultipartPresenterMap.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Behc.Mvp.Presenters.Factories; 3 | 4 | namespace Behc.Mvp.Presenters 5 | { 6 | public class MultipartPresenterMap : IPresenterMap 7 | { 8 | private readonly List _maps; 9 | 10 | public MultipartPresenterMap() 11 | { 12 | _maps = new List(4); 13 | } 14 | 15 | public void AddMap(IPresenterMap map) 16 | { 17 | // latest map goes first, it needs to be able to override other maps 18 | _maps.Insert(0, map); 19 | } 20 | 21 | public void RemoveMap(IPresenterMap map) 22 | { 23 | _maps.Remove(map); 24 | } 25 | 26 | public IPresenterFactory TryGetPresenterFactory(object model) 27 | { 28 | foreach (IPresenterMap map in _maps) 29 | { 30 | IPresenterFactory factory = map.TryGetPresenterFactory(model); 31 | if (factory != null) 32 | { 33 | return factory; 34 | } 35 | } 36 | 37 | return null; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/IPresenterMap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Behc.Mvp.Presenters.Factories; 3 | using UnityEngine; 4 | 5 | namespace Behc.Mvp.Presenters 6 | { 7 | public interface IPresenterMap 8 | { 9 | public IPresenterFactory TryGetPresenterFactory(object model); 10 | } 11 | 12 | public static class PresenterMapExtensions 13 | { 14 | public static IPresenter CreatePresenter(this IPresenterMap map, object model, RectTransform contentTransform) 15 | { 16 | IPresenterFactory factory = map.TryGetPresenterFactory(model); 17 | if (factory == null) 18 | throw new Exception($"No PresenterFactory found for '{model.GetType().Name}' model!"); 19 | 20 | return factory.CreatePresenter(contentTransform); 21 | } 22 | 23 | public static void DestroyPresenter(this IPresenterMap map, object model, IPresenter presenter) 24 | { 25 | IPresenterFactory factory = map.TryGetPresenterFactory(model); 26 | if (factory == null) 27 | throw new Exception($"No PresenterFactory found for '{model.GetType().Name}' model!"); 28 | 29 | factory.DestroyPresenter(presenter); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Runtime/Configuration/IDependencyResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | 4 | namespace Behc.Configuration 5 | { 6 | public interface IDependencyResolver 7 | { 8 | object Resolve([NotNull] Type type, string name, bool allowUnnamed); 9 | } 10 | 11 | public static class DependencyResolverExtensions 12 | { 13 | public static T Resolve(this IDependencyResolver resolver) where T : class 14 | { 15 | return resolver.Resolve(typeof(T), null, true) as T; 16 | } 17 | 18 | public static T Resolve(this IDependencyResolver resolver, string name) where T : class 19 | { 20 | return resolver.Resolve(typeof(T), name, false) as T; 21 | } 22 | 23 | public static T CreateInstance(this IDependencyResolver resolver) where T : class 24 | { 25 | return (T)MiniDiActivator.CreateInstance(resolver, typeof(T)); 26 | } 27 | 28 | public static T CreateInstance(this IDependencyResolver resolver, params object[] additionalParameters) where T : class 29 | { 30 | return (T)MiniDiActivator.CreateInstance(resolver, typeof(T), additionalParameters); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Runtime/Navigation/NavigationRegistry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Behc.Utils; 4 | using JetBrains.Annotations; 5 | using UnityEngine; 6 | 7 | namespace Behc.Navigation 8 | { 9 | public class NavigationRegistry : INavigationRegistry 10 | { 11 | private readonly Dictionary> _factories; 12 | 13 | public NavigationRegistry() 14 | { 15 | _factories = new Dictionary>(); 16 | } 17 | 18 | [MustUseReturnValue] 19 | public IDisposable Register(string name, IFactory navigableFactory) 20 | { 21 | _factories.Add(name, navigableFactory); 22 | 23 | return new GenericDisposable(() => _factories.Remove(name)); 24 | } 25 | 26 | public INavigable Create(string name, object parameters) 27 | { 28 | if (_factories.TryGetValue(name, out IFactory factory)) 29 | { 30 | return factory.Create(parameters); 31 | } 32 | 33 | Debug.Assert(false, $"Factory for '{name}' not found!"); 34 | return null; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataCollectionAnimatedOptions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Mvp.Presenters 4 | { 5 | [CreateAssetMenu(fileName = "DataCollectionAnimatedOptions", menuName = "MvpToolkit/DataCollectionAnimatedOptions", order = 100)] 6 | public class DataCollectionAnimatedOptions : ScriptableObject 7 | { 8 | [Header("Show")] public float ShowDuration = 0.2f; 9 | public Vector2 ShowOffset = Vector2.zero; 10 | public Vector2 ShowWeight = Vector2.zero; 11 | public AnimationCurve ShowCurve = AnimationCurve.Linear(0, 0, 1, 1); 12 | public float ShowPropagateDelay = 0; 13 | 14 | [Header("Hide")] public float HideDuration = 0.2f; 15 | public Vector2 HideOffset = Vector2.zero; 16 | public Vector2 HideWeight = Vector2.zero; 17 | public AnimationCurve HideCurve = AnimationCurve.Linear(0, 0, 1, 1); 18 | public float HidePropagateDelay = 0; 19 | 20 | [Header("Move")] public float MoveDuration = 0.2f; 21 | public AnimationCurve MoveCurve = AnimationCurve.Linear(0, 0, 1, 1); 22 | 23 | [Header("Delays")] public float MoveAfterHideDelay = 0; 24 | public float ShowAfterHideDelay = 0; 25 | public float ShowAfterMoveDelay = 0; 26 | } 27 | } -------------------------------------------------------------------------------- /Runtime/Utils/IInjectable.cs: -------------------------------------------------------------------------------- 1 | namespace Behc.Mvp.Presenter 2 | { 3 | public interface IInjectable 4 | { 5 | void Inject(T1 p1); 6 | } 7 | 8 | public interface IInjectable 9 | { 10 | void Inject(T1 p1, T2 p2); 11 | } 12 | 13 | public interface IInjectable 14 | { 15 | void Inject(T1 p1, T2 p2, T3 p3); 16 | } 17 | 18 | public interface IInjectable 19 | { 20 | void Inject(T1 p1, T2 p2, T3 p3, T4 p4); 21 | } 22 | 23 | public interface IInjectable 24 | { 25 | void Inject(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5); 26 | } 27 | 28 | public interface IInjectable 29 | { 30 | void Inject(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6); 31 | } 32 | 33 | public interface IInjectable 34 | { 35 | void Inject(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7); 36 | } 37 | 38 | public interface IInjectable 39 | { 40 | void Inject(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8); 41 | } 42 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # This .gitignore file should be placed at the root of your Unity project directory 2 | # 3 | # Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore 4 | # 5 | /[Ll]ibrary/ 6 | /[Tt]emp/ 7 | /[Oo]bj/ 8 | /[Bb]uild/ 9 | /[Bb]uilds/ 10 | /[Ll]ogs/ 11 | /[Mm]emoryCaptures/ 12 | 13 | # Asset meta data should only be ignored when the corresponding asset is also ignored 14 | !/[Aa]ssets/**/*.meta 15 | 16 | # Uncomment this line if you wish to ignore the asset store tools plugin 17 | # /[Aa]ssets/AssetStoreTools* 18 | 19 | # Autogenerated Jetbrains Rider plugin 20 | [Aa]ssets/Plugins/Editor/JetBrains* 21 | 22 | # Visual Studio cache directory 23 | .vs/ 24 | 25 | # Gradle cache directory 26 | .gradle/ 27 | 28 | # Autogenerated VS/MD/Consulo solution and project files 29 | ExportedObj/ 30 | .consulo/ 31 | *.csproj 32 | *.unityproj 33 | *.sln 34 | *.suo 35 | *.tmp 36 | *.user 37 | *.userprefs 38 | *.pidb 39 | *.booproj 40 | *.svd 41 | *.pdb 42 | *.mdb 43 | *.opendb 44 | *.VC.db 45 | 46 | # Unity3D generated meta files 47 | *.pidb.meta 48 | *.pdb.meta 49 | *.mdb.meta 50 | 51 | # Unity3D generated file on crash reports 52 | sysinfo.txt 53 | 54 | # Builds 55 | *.apk 56 | 57 | # Crashlytics generated file 58 | crashlytics-build.properties 59 | 60 | -------------------------------------------------------------------------------- /Runtime/Utils/TickerManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Behc.Utils 4 | { 5 | public class TickerManager 6 | { 7 | private readonly List _tickables = new List(4); 8 | private readonly List _added = new List(4); 9 | private readonly List _removed = new List(4); 10 | 11 | public void Track(ITickable tickable) 12 | { 13 | _added.Add(tickable); 14 | _removed.Remove(tickable); 15 | } 16 | 17 | public void Untrack(ITickable tickable) 18 | { 19 | _added.Remove(tickable); 20 | _removed.Add(tickable); 21 | } 22 | 23 | public void Update() 24 | { 25 | foreach (ITickable tickable in _removed) 26 | { 27 | _tickables.Remove(tickable); 28 | } 29 | _removed.Clear(); 30 | 31 | foreach (ITickable tickable in _added) 32 | { 33 | _tickables.Add(tickable); 34 | } 35 | _added.Clear(); 36 | 37 | foreach (ITickable tickable in _tickables) 38 | { 39 | tickable.OnTick(); 40 | } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/GridLayoutOptions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.Mvp.Presenters.Layout 4 | { 5 | [CreateAssetMenu(fileName = "GridLayoutOptions", menuName = "MvpToolkit/GridLayoutOptions", order = 300)] 6 | public class GridLayoutOptions : CollectionLayoutOptions 7 | { 8 | public enum OriginType 9 | { 10 | TOP_LEFT, 11 | TOP_RIGHT, 12 | BOTTOM_LEFT, 13 | BOTTOM_RIGHT, 14 | } 15 | 16 | public enum OrderType 17 | { 18 | ROW_MAJOR, //fill rows first, expands width 19 | COLUMN_MAJOR, //fill columns first, expands height 20 | } 21 | 22 | public enum AlignType 23 | { 24 | ORIGIN, 25 | CENTER, 26 | OPPOSITE, 27 | EXPAND_GAP, 28 | EXPAND_ELEMENT, 29 | } 30 | 31 | public float GapWidth = 10; 32 | public float GapHeight = 10; 33 | public float ElementWidth = 100; 34 | public float ElementHeight = 100; 35 | public RectOffset Padding = new RectOffset(); 36 | public OriginType Origin; 37 | public OrderType Order; 38 | public AlignType Align; 39 | public int MajorElementsMin; //defaults to 0 40 | public int MajorElementsMax; //defaults to 0 - no upper limit 41 | 42 | public override ICollectionLayout CreateLayout() 43 | { 44 | return new GridLayout(this); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Runtime/Navigation/BackButtonManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Behc.Utils; 4 | using JetBrains.Annotations; 5 | 6 | namespace Behc.Navigation 7 | { 8 | public class BackButtonManager 9 | { 10 | private struct Description 11 | { 12 | public int Priority; 13 | public Func Handler; 14 | } 15 | 16 | private readonly List _handlers = new List(16); 17 | 18 | //handler returns true if consumed 19 | [MustUseReturnValue] 20 | public IDisposable RegisterHandler(Func handler, int priority) 21 | { 22 | int insertAt = _handlers.Count; 23 | for (int i = 0; i < _handlers.Count; i++) 24 | { 25 | if (_handlers[i].Priority > priority) 26 | { 27 | insertAt = i; 28 | break; 29 | } 30 | } 31 | 32 | Description description = new Description { Priority = priority, Handler = handler }; 33 | _handlers.Insert(insertAt, description); 34 | return new GenericDisposable(() => { _handlers.Remove(description); }); 35 | } 36 | 37 | public void BackButtonClicked() 38 | { 39 | for (int i = _handlers.Count; i > 0; i--) 40 | { 41 | if (_handlers[i - 1].Handler()) 42 | break; 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Runtime/MiniTween/Extensions/ImageTweenExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | namespace Behc.MiniTween.Extensions 5 | { 6 | public static class ImageTweenExtensions 7 | { 8 | public static ITween AnimateColor(this Image img, ITweenSystem system, Color to, float duration) 9 | { 10 | return system.Animate(img, SetColor, new Vector4(img.color.r, img.color.g, img.color.b, img.color.a), new Vector4(to.r, to.g, to.b, to.a), duration); 11 | } 12 | 13 | public static ITween AnimateAlpha(this Image img, ITweenSystem system, float to, float duration) 14 | { 15 | return system.Animate(img, SetAlpha, new Vector4(0, 0, 0, img.color.a), new Vector4(0, 0, 0, to), duration); 16 | } 17 | 18 | public static ITween AnimateFillAmount(this Image img, ITweenSystem system, float to, float duration) 19 | { 20 | return system.Animate(img, SetFillAmount, new Vector4(0, 0, 0, img.fillAmount), new Vector4(0, 0, 0, to), duration); 21 | } 22 | 23 | private static void SetColor(object img, Vector4 value) => ((Image)img).color = new Color(value.x, value.y, value.z, value.w); 24 | 25 | private static void SetAlpha(object img, Vector4 value) 26 | { 27 | Color src = ((Image)img).color; 28 | src.a = value.w; 29 | ((Image)img).color = src; 30 | } 31 | 32 | private static void SetFillAmount(object img, Vector4 value) => ((Image)img).fillAmount = value.w; 33 | } 34 | } -------------------------------------------------------------------------------- /Documentation~/tween.md: -------------------------------------------------------------------------------- 1 | ## MiniTween 2 | 3 | Very basic tweening engine. Only supports simple animation, no sequences or complex parameters like looping. 4 | 5 | Some built-in components of Mvp uses it for curtain animation or simple sliding movement. 6 | 7 | There is no static/singleton instance. To obtain one, you need to call GetInstance() from scriptable object provider. 8 | As long as there is only one object, returned instance will be the same. 9 | 10 | > ⓘ You can replace implementation of scriptable object provider for testing purposes. 11 | 12 | > ⚠️ When using addressables it is very easy to duplicate scriptable objects. Make sure MiniTweenOptions asset is marked as addressable. 13 | 14 | public class ExamplePanelPresenter : PanelBase 15 | { 16 | //... 17 | [SerializeField] private CanvasGroup _canvasGroup; 18 | [SerializeField] private AbstractProvider _miniTweenProvider; 19 | 20 | protected override void OnBind(bool prepareForAnimation) 21 | { 22 | // initialize some stuff 23 | 24 | // set alpha to 0 for animated path 25 | _canvasGroup.alpha = prepareForAnimation ? 0 : 1; 26 | } 27 | 28 | protected override void OnAnimateShow(float startTime, Action onFinish) 29 | { 30 | _canvasGroup.AnimateAlpha( _miniTweenProvider.GetInstance(), 1.0f, 0.3f).SetCompleteCallback(onFinish); 31 | } 32 | } 33 | 34 | > ⓘ You can assign provider asset for any script, so Unity editor will automatically set it in edit mode. Useful for frequently used components. -------------------------------------------------------------------------------- /Runtime/Utils/EventsExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Behc.Utils; 3 | using JetBrains.Annotations; 4 | using UnityEngine.Events; 5 | 6 | namespace Behc.Mvp.Utils 7 | { 8 | public static class EventsExtensions 9 | { 10 | [MustUseReturnValue] 11 | public static IDisposable Subscribe(this UnityEvent e, UnityAction a) 12 | { 13 | e.AddListener(a); 14 | return new GenericDisposable(() => e.RemoveListener(a)); 15 | } 16 | 17 | [MustUseReturnValue] 18 | public static IDisposable Subscribe(this UnityEvent e, UnityAction a) 19 | { 20 | e.AddListener(a); 21 | return new GenericDisposable(() => e.RemoveListener(a)); 22 | } 23 | 24 | [MustUseReturnValue] 25 | public static IDisposable Subscribe(this UnityEvent e, UnityAction a) 26 | { 27 | e.AddListener(a); 28 | return new GenericDisposable(() => e.RemoveListener(a)); 29 | } 30 | 31 | [MustUseReturnValue] 32 | public static IDisposable Subscribe(this UnityEvent e, UnityAction a) 33 | { 34 | e.AddListener(a); 35 | return new GenericDisposable(() => e.RemoveListener(a)); 36 | } 37 | 38 | [MustUseReturnValue] 39 | public static IDisposable Subscribe(this UnityEvent e, UnityAction a) 40 | { 41 | e.AddListener(a); 42 | return new GenericDisposable(() => e.RemoveListener(a)); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/FixedVerticalListLayout.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Behc.Mvp.Presenters.Layout 5 | { 6 | public class FixedVerticalListLayout : ICollectionLayout 7 | { 8 | private readonly ListLayoutOptions _layoutOptions; 9 | 10 | private float _width; 11 | 12 | public FixedVerticalListLayout(ListLayoutOptions layoutOptions) 13 | { 14 | _layoutOptions = layoutOptions; 15 | } 16 | 17 | public void SetContentSize(float width, float height) 18 | { 19 | _width = width; 20 | } 21 | 22 | public Rect EvaluateRect(int index, IReadOnlyList rects, Vector2 requestedSize, float requestedGap) 23 | { 24 | float offset = index * (_layoutOptions.ElementSize + _layoutOptions.GapSize) + _layoutOptions.Padding.top; 25 | 26 | return new Rect(_layoutOptions.Padding.left, offset, _width - _layoutOptions.Padding.horizontal, _layoutOptions.ElementSize); 27 | } 28 | 29 | public Vector2 GetApproximatedContentSize(Vector2 defaultSize, int itemsCount) 30 | { 31 | return new Vector2(defaultSize.x, itemsCount * _layoutOptions.ElementSize + Mathf.Max(0, itemsCount - 1) * _layoutOptions.GapSize + _layoutOptions.Padding.vertical); 32 | } 33 | 34 | public Vector2 GetOptimalContentSize(Vector2 defaultSize, IReadOnlyList rects) 35 | { 36 | return GetApproximatedContentSize(defaultSize, rects.Count); 37 | } 38 | 39 | public bool RebuildRequired(bool widthChanged, bool heightChanged) 40 | { 41 | return widthChanged; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/FixedHorizontalListLayout.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Behc.Mvp.Presenters.Layout 5 | { 6 | public class FixedHorizontalListLayout : ICollectionLayout 7 | { 8 | private readonly ListLayoutOptions _layoutOptions; 9 | 10 | private float _height; 11 | 12 | public FixedHorizontalListLayout(ListLayoutOptions layoutOptions) 13 | { 14 | _layoutOptions = layoutOptions; 15 | } 16 | 17 | public void SetContentSize(float width, float height) 18 | { 19 | _height = height; 20 | } 21 | 22 | public Rect EvaluateRect(int index, IReadOnlyList rects, Vector2 requestedSize, float requestedGap) 23 | { 24 | float offset = index * (_layoutOptions.ElementSize + _layoutOptions.GapSize) + _layoutOptions.Padding.left; 25 | 26 | return new Rect(offset, _layoutOptions.Padding.top, _layoutOptions.ElementSize, _height - _layoutOptions.Padding.vertical); 27 | } 28 | 29 | public Vector2 GetApproximatedContentSize(Vector2 defaultSize, int itemsCount) 30 | { 31 | return new Vector2(itemsCount * _layoutOptions.ElementSize + Mathf.Max(0, itemsCount - 1) * _layoutOptions.GapSize + _layoutOptions.Padding.horizontal, defaultSize.y); 32 | } 33 | 34 | public Vector2 GetOptimalContentSize(Vector2 defaultSize, IReadOnlyList rects) 35 | { 36 | return GetApproximatedContentSize(defaultSize, rects.Count); 37 | } 38 | 39 | public bool RebuildRequired(bool widthChanged, bool heightChanged) 40 | { 41 | return heightChanged; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/PanelCanvasPresenter.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.Assertions; 3 | using UnityEngine.UI; 4 | 5 | namespace Behc.Mvp.Presenters 6 | { 7 | public class PanelCanvasPresenter : PanelPresenterBase, IPresenterSorting where T : class 8 | { 9 | #pragma warning disable CS0649 10 | [SerializeField] protected Canvas _canvas; 11 | [SerializeField] protected GraphicRaycaster _graphicRaycaster; 12 | #pragma warning restore CS0649 13 | 14 | public sealed override void Initialize(IPresenterMap presenterMap, PresenterUpdateKernel kernel) 15 | { 16 | base.Initialize(presenterMap, kernel); 17 | 18 | _graphicRaycaster.enabled = false; 19 | } 20 | 21 | public sealed override void Activate() 22 | { 23 | base.Activate(); 24 | 25 | _graphicRaycaster.enabled = true; 26 | } 27 | 28 | public sealed override void Deactivate() 29 | { 30 | _graphicRaycaster.enabled = false; 31 | 32 | base.Deactivate(); 33 | } 34 | 35 | public void SetSortingOrder(int baseSortingOrder, int sortingLayerId) 36 | { 37 | Assert.IsTrue(gameObject.activeInHierarchy, $"Cannot override sorting for inactive {gameObject.name} canvas!"); 38 | 39 | _canvas.overrideSorting = true; 40 | _canvas.sortingLayerID = sortingLayerId; 41 | _canvas.sortingOrder = baseSortingOrder; 42 | 43 | OnSetSortingOrder(baseSortingOrder, sortingLayerId); 44 | } 45 | 46 | protected virtual void OnSetSortingOrder(int baseSortingOrder, int sortingLayerId) 47 | { 48 | //NOOP 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /Samples~/SimpleGame/SimpleGameSampleWindow.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace DataPresentersGallerySample 5 | { 6 | public class SimpleGameSampleWindow : EditorWindow 7 | { 8 | [MenuItem ("MvpToolkit/Simple Game Sample")] 9 | public static void ShowWindow() 10 | { 11 | GetWindow(typeof(SimpleGameSampleWindow)); 12 | } 13 | 14 | private void OnGUI () 15 | { 16 | if (SimpleGameSampleInstaller.IsSampleInstalled()) 17 | { 18 | EditorGUILayout.HelpBox("Data Presenters Gallery Sample is already installed.\nOpen SimpleGameRoot scene for Play mode.", MessageType.Info); 19 | return; 20 | } 21 | 22 | if(SimpleGameSampleInstaller.HasTextMeshProPackage()) 23 | { 24 | if (SimpleGameSampleInstaller.HasTextMeshProEssentials()) 25 | { 26 | EditorGUILayout.HelpBox("All requirements are met", MessageType.Info); 27 | } 28 | else 29 | { 30 | EditorGUILayout.HelpBox("TextMesh PRO essentials are missing!\nPlease import essentials from TextMesh Pro settings panel.", MessageType.Error); 31 | } 32 | } 33 | else 34 | { 35 | EditorGUILayout.HelpBox("TextMesh PRO package is missing!\nPlease import package and essentials.", MessageType.Error); 36 | } 37 | 38 | GUI.enabled = SimpleGameSampleInstaller.HasTextMeshProPackage() && SimpleGameSampleInstaller.HasTextMeshProEssentials(); 39 | if( GUILayout.Button( "Install Sample") ) 40 | { 41 | SimpleGameSampleInstaller.InstallAssetPackage(); 42 | } 43 | 44 | GUI.enabled = true; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Runtime/MiniTween/Extensions/TextMeshProTweenExtensions.cs: -------------------------------------------------------------------------------- 1 | #if BEHC_MVPTOOLKIT_TEXTMESHPRO 2 | using TMPro; 3 | using UnityEngine; 4 | 5 | namespace Behc.MiniTween.Extensions 6 | { 7 | public static class TextMeshProTweenExtensions 8 | { 9 | public static ITween AnimateColor(this TextMeshProUGUI text, ITweenSystem system, Color to, float duration) 10 | { 11 | return system.Animate(text, SetColor, new Vector4(text.color.r, text.color.g, text.color.b, text.color.a), new Vector4(to.r, to.g, to.b, to.a), duration); 12 | } 13 | 14 | public static ITween AnimateAlpha(this TextMeshProUGUI text, ITweenSystem system, float to, float duration) 15 | { 16 | return system.Animate(text, SetAlpha, new Vector4(0, 0, 0, text.color.a), new Vector4(0, 0, 0, to), duration); 17 | } 18 | 19 | public static ITween AnimateMaxCharactersVisible(this TextMeshProUGUI text, ITweenSystem system, float to, float duration) 20 | { 21 | return system.Animate(text, SetAlpha, new Vector4(0, 0, 0, (float)text.maxVisibleCharacters / text.textInfo.characterCount), new Vector4(0, 0, 0, to), duration); 22 | } 23 | 24 | private static void SetColor(object text, Vector4 value) => ((TextMeshProUGUI) text).color = new Color(value.x, value.y, value.z, value.w); 25 | 26 | private static void SetAlpha(object text, Vector4 value) 27 | { 28 | Color src = ((TextMeshProUGUI) text).color; 29 | src.a = value.w; 30 | ((TextMeshProUGUI) text).color = src; 31 | } 32 | 33 | private static void SetMaxCharactersVisible(object text, Vector4 value) 34 | { 35 | TextMeshProUGUI tmp = (TextMeshProUGUI)text; 36 | tmp.maxVisibleCharacters = Mathf.RoundToInt(value.w * tmp.textInfo.characterCount); 37 | } 38 | } 39 | } 40 | #endif -------------------------------------------------------------------------------- /Runtime/Configuration/SceneConfigurator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using JetBrains.Annotations; 4 | using UnityEngine; 5 | 6 | namespace Behc.Configuration 7 | { 8 | // ReSharper disable once ClassWithVirtualMembersNeverInherited.Global 9 | public class SceneConfigurator : MonoBehaviour, IConfigurator 10 | { 11 | [SerializeField] private SceneConfigurator[] _subConfigurators; 12 | 13 | [NonSerialized] private List _disposables; 14 | 15 | void IConfigurator.Load(IDependencyResolver resolver) 16 | { 17 | MiniDiActivator.CallMethod(resolver, this, "OnLoad"); 18 | 19 | if (_subConfigurators != null) 20 | { 21 | foreach (IConfigurator sc in _subConfigurators) 22 | { 23 | sc.Load(resolver); 24 | } 25 | } 26 | } 27 | 28 | void IConfigurator.Unload(IDependencyResolver resolver) 29 | { 30 | if (_subConfigurators != null) 31 | { 32 | for (int i = _subConfigurators.Length; i > 0; i--) 33 | { 34 | IConfigurator sc = _subConfigurators[i - 1]; 35 | sc.Unload(resolver); 36 | } 37 | } 38 | 39 | MiniDiActivator.CallMethod(resolver, this, "OnUnload"); 40 | 41 | if (_disposables != null) 42 | { 43 | foreach (IDisposable disposable in _disposables) 44 | { 45 | disposable.Dispose(); 46 | } 47 | 48 | _disposables.Clear(); 49 | _disposables = null; 50 | } 51 | } 52 | 53 | protected void DisposeOnUnload([NotNull] IDisposable disposable) 54 | { 55 | _disposables ??= new List(); 56 | _disposables.Add(disposable); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /Runtime/Utils/IFactory.cs: -------------------------------------------------------------------------------- 1 | namespace Behc.Utils 2 | { 3 | public interface IFactory 4 | { 5 | TInstance Create(); 6 | } 7 | 8 | public interface IFactory 9 | { 10 | TInstance Create(TParam1 param1); 11 | } 12 | 13 | public interface IFactory 14 | { 15 | TInstance Create(TParam1 param1, TParam2 param2); 16 | } 17 | 18 | public interface IFactory 19 | { 20 | TInstance Create(TParam1 param1, TParam2 param2, TParam3 param3); 21 | } 22 | 23 | public interface IFactory 24 | { 25 | TInstance Create(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4); 26 | } 27 | 28 | public interface IFactory 29 | { 30 | TInstance Create(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5); 31 | } 32 | 33 | public interface IFactory 34 | { 35 | TInstance Create(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5, TParam6 param6); 36 | } 37 | 38 | public interface IFactory 39 | { 40 | TInstance Create(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5, TParam6 param6, TParam7 param7); 41 | } 42 | 43 | public interface IFactory 44 | { 45 | TInstance Create(TParam1 param1, TParam2 param2, TParam3 param3, TParam4 param4, TParam5 param5, TParam6 param6, TParam7 param7, TParam8 param8); 46 | } 47 | } -------------------------------------------------------------------------------- /Runtime/Utils/SmallSet.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Behc.Mvp.Utils 4 | { 5 | public struct SmallSet //: ISet - lots on non-essential stuff here 6 | { 7 | private object _item; 8 | private HashSet _set; //for small items count List<> might be enough? 9 | 10 | public int Count 11 | { 12 | get 13 | { 14 | if (_set != null) 15 | return _set.Count; 16 | 17 | return _item != null ? 1 : 0; 18 | } 19 | } 20 | 21 | public bool Add(object item) 22 | { 23 | if (item == null) 24 | return false; 25 | 26 | if (_set != null) 27 | return _set.Add(item); 28 | 29 | if (_item == item) 30 | return false; 31 | 32 | if (_item == null) 33 | { 34 | _item = item; 35 | return true; 36 | } 37 | 38 | _set = new HashSet { _item, item }; 39 | _item = null; 40 | 41 | return true; 42 | } 43 | 44 | public bool Remove(object item) 45 | { 46 | if (item == null) 47 | return false; 48 | 49 | if (_set != null) 50 | return _set.Remove(item); 51 | 52 | if (_item == item) 53 | { 54 | _item = null; 55 | return true; 56 | } 57 | 58 | return false; 59 | } 60 | 61 | public bool Contains(object item) 62 | { 63 | if (item == null) 64 | return false; 65 | 66 | if (_set != null) 67 | return _set.Contains(item); 68 | 69 | return _item == item; 70 | } 71 | 72 | public void Clear() 73 | { 74 | _set?.Clear(); 75 | _item = null; 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /Samples~/DataPresentersGallery/DataPresentersGallerySampleWindow.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace DataPresentersGallerySample 5 | { 6 | public class DataPresentersGallerySampleWindow : EditorWindow 7 | { 8 | [MenuItem ("MvpToolkit/Data Presenters Gallery Sample")] 9 | public static void ShowWindow() 10 | { 11 | GetWindow(typeof(DataPresentersGallerySampleWindow)); 12 | } 13 | 14 | private void OnGUI () 15 | { 16 | if (DataPresentersGallerySampleInstaller.IsSampleInstalled()) 17 | { 18 | EditorGUILayout.HelpBox("Data Presenters Gallery Sample is already installed.\nOpen DataPresentersGalleryRoot scene for Play mode.", MessageType.Info); 19 | return; 20 | } 21 | 22 | if(DataPresentersGallerySampleInstaller.HasTextMeshProPackage()) 23 | { 24 | if (DataPresentersGallerySampleInstaller.HasTextMeshProEssentials()) 25 | { 26 | EditorGUILayout.HelpBox("All requirements are met", MessageType.Info); 27 | } 28 | else 29 | { 30 | EditorGUILayout.HelpBox("TextMesh PRO essentials are missing!\nPlease import essentials from TextMesh Pro settings panel.", MessageType.Error); 31 | } 32 | } 33 | else 34 | { 35 | EditorGUILayout.HelpBox("TextMesh PRO package is missing!\nPlease import package and essentials.", MessageType.Error); 36 | } 37 | 38 | GUI.enabled = DataPresentersGallerySampleInstaller.HasTextMeshProPackage() && DataPresentersGallerySampleInstaller.HasTextMeshProEssentials(); 39 | if( GUILayout.Button( "Install Sample") ) 40 | { 41 | DataPresentersGallerySampleInstaller.InstallAssetPackage(); 42 | } 43 | 44 | GUI.enabled = true; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Runtime/MiniTween/Extensions/RectTransformTweenExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Behc.MiniTween.Extensions 4 | { 5 | public static class RectTransformTweenExtensions 6 | { 7 | public static ITween AnimateAnchoredPosition(this RectTransform rt, ITweenSystem system, Vector2 to, float duration) 8 | { 9 | return system.Animate(rt, SetAnchoredPosition, rt.anchoredPosition, to, duration); 10 | } 11 | 12 | public static ITween AnimateScale(this RectTransform rt, ITweenSystem system, Vector3 to, float duration) 13 | { 14 | return system.Animate(rt, SetScale, rt.localScale, to, duration); 15 | } 16 | 17 | public static ITween AnimateSizeDelta(this RectTransform rt, ITweenSystem system, Vector2 to, float duration) 18 | { 19 | return system.Animate(rt, SetSizeDelta, rt.sizeDelta, to, duration); 20 | } 21 | 22 | public static ITween AnimateOffsetMin(this RectTransform rt, ITweenSystem system, Vector2 to, float duration) 23 | { 24 | return system.Animate(rt, SetOffsetMin, rt.offsetMin, to, duration); 25 | } 26 | 27 | public static ITween AnimateOffsetMax(this RectTransform rt, ITweenSystem system, Vector2 to, float duration) 28 | { 29 | return system.Animate(rt, SetOffsetMax, rt.offsetMax, to, duration); 30 | } 31 | 32 | private static void SetAnchoredPosition(object rt, Vector4 value) => ((RectTransform) rt).anchoredPosition = value; 33 | private static void SetScale(object rt, Vector4 value) => ((RectTransform) rt).localScale = value; 34 | private static void SetSizeDelta(object rt, Vector4 value) => ((RectTransform) rt).sizeDelta = value; 35 | private static void SetOffsetMin(object rt, Vector4 value) => ((RectTransform) rt).offsetMin = value; 36 | private static void SetOffsetMax(object rt, Vector4 value) => ((RectTransform) rt).offsetMax = value; 37 | } 38 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/VariableVerticalListLayout.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Behc.Mvp.Presenters.Layout 5 | { 6 | public class VariableVerticalListLayout : ICollectionLayout 7 | { 8 | private readonly ListLayoutOptions _layoutOptions; 9 | 10 | private float _width; 11 | 12 | public VariableVerticalListLayout(ListLayoutOptions layoutOptions) 13 | { 14 | _layoutOptions = layoutOptions; 15 | } 16 | 17 | public void SetContentSize(float width, float height) 18 | { 19 | _width = width; 20 | } 21 | 22 | public Rect EvaluateRect(int index, IReadOnlyList rects, Vector2 requestedSize, float requestedGap) 23 | { 24 | Rect lastRect = index > 0 ? rects[index - 1] : new Rect(_layoutOptions.Padding.left, _layoutOptions.Padding.top, _width - _layoutOptions.Padding.horizontal, 0); 25 | 26 | float gap = requestedGap >= 0 ? requestedGap : _layoutOptions.GapSize; 27 | if (index <= 0) gap = 0; 28 | float size = requestedSize.y > 0 ? requestedSize.y : _layoutOptions.ElementSize; 29 | 30 | return new Rect(_layoutOptions.Padding.left, lastRect.yMax + gap, _width - _layoutOptions.Padding.horizontal, size); 31 | } 32 | 33 | public Vector2 GetApproximatedContentSize(Vector2 defaultSize, int itemsCount) 34 | { 35 | return new Vector2(defaultSize.x, itemsCount * _layoutOptions.ElementSize + Mathf.Max(0, itemsCount - 1) * _layoutOptions.GapSize + _layoutOptions.Padding.vertical); 36 | } 37 | 38 | public Vector2 GetOptimalContentSize(Vector2 defaultSize, IReadOnlyList rects) 39 | { 40 | return rects.Count == 0 ? new Vector2(defaultSize.x, _layoutOptions.Padding.vertical) : new Vector2(defaultSize.x, rects[rects.Count - 1].yMax + _layoutOptions.Padding.bottom); 41 | } 42 | 43 | public bool RebuildRequired(bool widthChanged, bool heightChanged) 44 | { 45 | return widthChanged; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Layout/VariableHorizontalListLayout.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Behc.Mvp.Presenters.Layout 5 | { 6 | public class VariableHorizontalListLayout : ICollectionLayout 7 | { 8 | private readonly ListLayoutOptions _layoutOptions; 9 | 10 | private float _height; 11 | 12 | public VariableHorizontalListLayout(ListLayoutOptions layoutOptions) 13 | { 14 | _layoutOptions = layoutOptions; 15 | } 16 | 17 | public void SetContentSize(float width, float height) 18 | { 19 | _height = height; 20 | } 21 | 22 | public Rect EvaluateRect(int index, IReadOnlyList rects, Vector2 requestedSize, float requestedGap) 23 | { 24 | Rect lastRect = index > 0 ? rects[index - 1] : new Rect(_layoutOptions.Padding.left, _layoutOptions.Padding.top, 0, _height - _layoutOptions.Padding.vertical); 25 | 26 | float gap = requestedGap >= 0 ? requestedGap : _layoutOptions.GapSize; 27 | if (index <= 0) gap = 0; 28 | float size = requestedSize.x > 0 ? requestedSize.x : _layoutOptions.ElementSize; 29 | 30 | return new Rect(lastRect.xMax + gap, _layoutOptions.Padding.top, size, _height - _layoutOptions.Padding.vertical); 31 | } 32 | 33 | public Vector2 GetApproximatedContentSize(Vector2 defaultSize, int itemsCount) 34 | { 35 | return new Vector2(itemsCount * _layoutOptions.ElementSize + Mathf.Max(0, itemsCount - 1) * _layoutOptions.GapSize + _layoutOptions.Padding.horizontal, defaultSize.y); 36 | } 37 | 38 | public Vector2 GetOptimalContentSize(Vector2 defaultSize, IReadOnlyList rects) 39 | { 40 | return rects.Count == 0 ? new Vector2(_layoutOptions.Padding.horizontal, defaultSize.y) : new Vector2(rects[rects.Count - 1].xMax + _layoutOptions.Padding.right, defaultSize.y); 41 | } 42 | 43 | public bool RebuildRequired(bool widthChanged, bool heightChanged) 44 | { 45 | return heightChanged; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Factories/SimpleFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | using UnityEngine; 4 | using Object = UnityEngine.Object; 5 | 6 | namespace Behc.Mvp.Presenters.Factories 7 | { 8 | public class SimpleFactory : IPresenterFactory 9 | { 10 | private readonly GameObject _prefab; 11 | private readonly PresenterMap _presenterMap; 12 | private readonly PresenterUpdateKernel _updateKernel; 13 | 14 | public SimpleFactory(GameObject prefab, PresenterMap presenterMap, PresenterUpdateKernel updateKernel) 15 | { 16 | _prefab = prefab; 17 | _presenterMap = presenterMap; 18 | _updateKernel = updateKernel; 19 | } 20 | 21 | public IPresenter CreatePresenter(RectTransform parentTransform) 22 | { 23 | GameObject instance = Object.Instantiate(_prefab, parentTransform, false); 24 | IPresenter presenter = instance.GetComponent(); 25 | 26 | presenter.Initialize(_presenterMap, _updateKernel); 27 | instance.SetActive(false); 28 | 29 | return presenter; 30 | } 31 | 32 | public void DestroyPresenter(IPresenter presenter) 33 | { 34 | presenter.Destroy(); 35 | 36 | Object.Destroy(presenter.RectTransform.gameObject); 37 | } 38 | 39 | public void Dispose() 40 | { 41 | //NOOP 42 | } 43 | } 44 | 45 | public static class SimpleFactoryExtensions 46 | { 47 | [MustUseReturnValue] 48 | public static IDisposable RegisterFactory(this PresenterMap presenterMap, GameObject prefab, PresenterUpdateKernel updateKernel) 49 | { 50 | return presenterMap.Register(new SimpleFactory(prefab, presenterMap, updateKernel)); 51 | } 52 | 53 | [MustUseReturnValue] 54 | public static IDisposable RegisterFactory(this PresenterMap presenterMap, GameObject prefab, PresenterUpdateKernel updateKernel, Func predicate) 55 | { 56 | return presenterMap.Register(new SimpleFactory(prefab, presenterMap, updateKernel), predicate); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Models/TrackableReactiveModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | 5 | namespace Behc.Mvp.Models 6 | { 7 | public class TrackableReactiveModel : ReactiveModel, ITrackable 8 | { 9 | private int _refCount; 10 | private List _disposeOnEnd; 11 | private CancellationTokenSource _cancellation; 12 | 13 | public bool IsActive => _refCount > 0; 14 | 15 | public void Acquire() 16 | { 17 | int rc = _refCount; 18 | _refCount++; 19 | 20 | if (rc == 0) 21 | { 22 | OnBegin(); 23 | } 24 | } 25 | 26 | public void Release() 27 | { 28 | _refCount--; 29 | if (_refCount != 0) 30 | return; 31 | 32 | if (_cancellation != null) 33 | { 34 | _cancellation.Cancel(); 35 | _cancellation.Dispose(); 36 | _cancellation = null; 37 | } 38 | 39 | OnEnd(); 40 | 41 | if (_disposeOnEnd != null) 42 | { 43 | foreach (IDisposable disposable in _disposeOnEnd) 44 | { 45 | disposable.Dispose(); 46 | } 47 | } 48 | } 49 | 50 | // Creates CancellationToken that will be cancelled when nothing is using this model anymore. 51 | protected CancellationToken CancelOnEnd() 52 | { 53 | _cancellation ??= new CancellationTokenSource(); 54 | 55 | return _cancellation.Token; 56 | } 57 | 58 | // Automatically disposes an object when nothing is using this model anymore. 59 | protected void DisposeOnEnd(IDisposable disposable) 60 | { 61 | _disposeOnEnd ??= new List(); 62 | 63 | _disposeOnEnd.Add(disposable); 64 | } 65 | 66 | // Called when first presenter starts using this model. 67 | protected virtual void OnBegin() 68 | { 69 | } 70 | 71 | // Called when last presenter stops using this model. 72 | protected virtual void OnEnd() 73 | { 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Components/Curtain.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.Events; 3 | using UnityEngine.EventSystems; 4 | 5 | namespace Behc.Mvp.Components 6 | { 7 | public abstract class Curtain : MonoBehaviour, IPointerClickHandler, IPointerDownHandler 8 | { 9 | public enum TriggerModeType 10 | { 11 | ANY_BUTTON_DOWN, 12 | LEFT_BUTTON_DOWN, 13 | RIGHT_BUTTON_DOWN, 14 | MIDDLE_BUTTON_DOWN, 15 | ANY_BUTTON_CLICK, 16 | LEFT_BUTTON_CLICK, 17 | RIGHT_BUTTON_CLICK, 18 | MIDDLE_BUTTON_CLICK, 19 | } 20 | 21 | public UnityEvent OnTrigger = new UnityEvent(); 22 | public TriggerModeType TriggerMode = TriggerModeType.ANY_BUTTON_CLICK; 23 | 24 | public abstract void Setup(bool visible, int order); 25 | public abstract void Show(int order); 26 | public abstract void Switch(int newOrder, int previousOrder); 27 | public abstract void Hide(); 28 | 29 | 30 | public void OnPointerClick(PointerEventData eventData) 31 | { 32 | switch (TriggerMode) 33 | { 34 | case TriggerModeType.ANY_BUTTON_CLICK: 35 | case TriggerModeType.LEFT_BUTTON_CLICK when eventData.button == PointerEventData.InputButton.Left: 36 | case TriggerModeType.RIGHT_BUTTON_CLICK when eventData.button == PointerEventData.InputButton.Right: 37 | case TriggerModeType.MIDDLE_BUTTON_CLICK when eventData.button == PointerEventData.InputButton.Middle: 38 | OnTrigger.Invoke(); 39 | break; 40 | } 41 | } 42 | 43 | public void OnPointerDown(PointerEventData eventData) 44 | { 45 | switch (TriggerMode) 46 | { 47 | case TriggerModeType.ANY_BUTTON_DOWN: 48 | case TriggerModeType.LEFT_BUTTON_DOWN when eventData.button == PointerEventData.InputButton.Left: 49 | case TriggerModeType.RIGHT_BUTTON_DOWN when eventData.button == PointerEventData.InputButton.Right: 50 | case TriggerModeType.MIDDLE_BUTTON_DOWN when eventData.button == PointerEventData.InputButton.Middle: 51 | OnTrigger.Invoke(); 52 | break; 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /Runtime/Configuration/Loaders/AddressableScriptableConfiguratorLoader.cs: -------------------------------------------------------------------------------- 1 | #if BEHC_MVPTOOLKIT_ADDRESSABLES 2 | using System; 3 | using UnityEngine; 4 | using UnityEngine.AddressableAssets; 5 | using UnityEngine.ResourceManagement.AsyncOperations; 6 | 7 | namespace Behc.Configuration.Loaders 8 | { 9 | public class AddressableScriptableConfiguratorLoader : IConfiguratorLoader 10 | { 11 | public ConfiguratorStatus Status { get; private set; } 12 | 13 | public float Progress => _handle.IsValid() ? _handle.PercentComplete : 1.0f; 14 | 15 | private readonly object _key; 16 | private AsyncOperationHandle _handle; 17 | 18 | public AddressableScriptableConfiguratorLoader(object key) 19 | { 20 | _key = key; 21 | Status = ConfiguratorStatus.UNLOADED; 22 | } 23 | 24 | public void Load(IDependencyResolver resolver, Action onComplete) 25 | { 26 | Debug.Assert(Status == ConfiguratorStatus.UNLOADED, $"Invalid status: '{Status}' for '{_key}' scriptable configurator!"); 27 | 28 | void Finished(AsyncOperationHandle obj) 29 | { 30 | IConfigurator configurator = obj.Result; 31 | try 32 | { 33 | configurator.Load(resolver); 34 | } 35 | catch (Exception e) 36 | { 37 | Debug.LogException(e); 38 | } 39 | 40 | Status = ConfiguratorStatus.LOADED; 41 | onComplete?.Invoke(); 42 | } 43 | 44 | Status = ConfiguratorStatus.LOADING; 45 | _handle = Addressables.LoadAssetAsync(_key); 46 | _handle.Completed += Finished; 47 | } 48 | 49 | public void Unload(IDependencyResolver resolver, Action onComplete) 50 | { 51 | Debug.Assert(Status == ConfiguratorStatus.LOADED, $"Invalid status: '{Status}' for '{_key}' scriptable configurator!"); 52 | 53 | IConfigurator configurator = _handle.Result; 54 | configurator.Unload(resolver); 55 | 56 | Addressables.Release(_handle); 57 | _handle = default; 58 | 59 | Status = ConfiguratorStatus.UNLOADED; 60 | onComplete?.Invoke(); 61 | } 62 | } 63 | } 64 | #endif -------------------------------------------------------------------------------- /Runtime/Configuration/Loaders/ResourceScriptableConfiguratorLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Behc.Configuration.Loaders 5 | { 6 | public class ResourceScriptableConfiguratorLoader : IConfiguratorLoader 7 | { 8 | public ConfiguratorStatus Status { get; private set; } 9 | public float Progress => _resourceRequest?.progress ?? 1.0f; 10 | 11 | private readonly string _resourcePath; 12 | 13 | private ResourceRequest _resourceRequest; 14 | private IConfigurator _configurator; 15 | 16 | public ResourceScriptableConfiguratorLoader(string resourcePath) 17 | { 18 | _resourcePath = resourcePath; 19 | 20 | Status = ConfiguratorStatus.UNLOADED; 21 | } 22 | 23 | public void Load(IDependencyResolver resolver, Action onComplete) 24 | { 25 | Debug.Assert(Status == ConfiguratorStatus.UNLOADED, $"Invalid status: '{Status}' for '{_resourcePath}' scriptable configurator!"); 26 | 27 | void Finished(AsyncOperation _) 28 | { 29 | _configurator = (IConfigurator)_resourceRequest.asset; 30 | _resourceRequest = null; 31 | 32 | try 33 | { 34 | _configurator.Load(resolver); 35 | } 36 | catch (Exception e) 37 | { 38 | Debug.LogException(e); 39 | } 40 | 41 | Status = ConfiguratorStatus.LOADED; 42 | onComplete?.Invoke(); 43 | } 44 | 45 | Status = ConfiguratorStatus.LOADING; 46 | _resourceRequest = Resources.LoadAsync(_resourcePath); 47 | _resourceRequest.completed += Finished; 48 | } 49 | 50 | public void Unload(IDependencyResolver resolver, Action onComplete) 51 | { 52 | Debug.Assert(Status == ConfiguratorStatus.LOADED, $"Invalid status: '{Status}' for '{_resourcePath}' scriptable configurator!"); 53 | 54 | try 55 | { 56 | _configurator.Unload(resolver); 57 | } 58 | catch (Exception e) 59 | { 60 | Debug.LogException(e); 61 | } 62 | 63 | _configurator = null; 64 | 65 | Status = ConfiguratorStatus.UNLOADED; 66 | onComplete?.Invoke(); 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Animations/FadeAnimation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Behc.MiniTween; 3 | using Behc.MiniTween.Extensions; 4 | using UnityEngine; 5 | 6 | namespace Behc.Mvp.Animations 7 | { 8 | public class FadeAnimation : IAnimator 9 | { 10 | private readonly FadeAnimationOptions _options; 11 | private readonly CanvasGroup _canvasGroup; 12 | 13 | private ITween _tween; 14 | 15 | public bool IsAnimating => _tween != null; 16 | 17 | public FadeAnimation(FadeAnimationOptions options, CanvasGroup canvasGroup) 18 | { 19 | _options = options; 20 | _canvasGroup = canvasGroup; 21 | } 22 | 23 | public void Setup(bool prepareForAnimation) 24 | { 25 | _canvasGroup.alpha = prepareForAnimation ? 0 : 1; 26 | } 27 | 28 | public void AnimateShow(float startTime, Action onFinish) 29 | { 30 | if (startTime >= _options.ShowDuration || _options.ShowDuration <= 0) 31 | { 32 | _canvasGroup.alpha = 1; 33 | 34 | onFinish?.Invoke(); 35 | return; 36 | } 37 | 38 | _tween = _canvasGroup.AnimateAlpha(_options.TweenProvider.GetInstance(), 1, _options.ShowDuration); 39 | _tween.SetId($"AnimateShow-{_canvasGroup.gameObject.name}"); 40 | _tween.SetCompleteCallback(() => 41 | { 42 | _tween = null; 43 | onFinish?.Invoke(); 44 | }); 45 | 46 | _tween.SetCurrentTime(startTime); 47 | } 48 | 49 | public void AnimateHide(float startTime, Action onFinish) 50 | { 51 | if (startTime >= _options.HideDuration || _options.HideDuration <= 0) 52 | { 53 | onFinish?.Invoke(); 54 | return; 55 | } 56 | 57 | _tween = _canvasGroup.AnimateAlpha(_options.TweenProvider.GetInstance(), 0, _options.HideDuration); 58 | _tween.SetId($"AnimateHide-{_canvasGroup.gameObject.name}"); 59 | _tween.SetCompleteCallback(() => 60 | { 61 | _tween = null; 62 | onFinish?.Invoke(); 63 | }); 64 | 65 | _tween.SetCurrentTime(startTime); 66 | } 67 | 68 | public void AbortAnimations() 69 | { 70 | _tween?.Complete(); 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Models/DataCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using JetBrains.Annotations; 4 | 5 | namespace Behc.Mvp.Models 6 | { 7 | public class DataCollection : ReactiveModel, IDataCollection 8 | { 9 | protected readonly List _data = new List(); 10 | 11 | public IReadOnlyCollection Data => _data; 12 | 13 | public void Add([NotNull] object item) 14 | { 15 | _data.Add(item); 16 | NotifyChanges(); 17 | } 18 | 19 | public void AddRange([ItemNotNull] IEnumerable items) 20 | { 21 | _data.AddRange(items); 22 | NotifyChanges(); 23 | } 24 | 25 | public void Remove(object item) 26 | { 27 | if (_data.Remove(item)) 28 | { 29 | NotifyChanges(); 30 | } 31 | } 32 | 33 | public void RemoveAll(Predicate match) 34 | { 35 | if (_data.RemoveAll(match) > 0) 36 | { 37 | NotifyChanges(); 38 | } 39 | } 40 | 41 | public void Clear() 42 | { 43 | _data.Clear(); 44 | NotifyChanges(); 45 | } 46 | 47 | public void Refresh() 48 | { 49 | NotifyChanges(); 50 | } 51 | } 52 | 53 | public class DataCollection : ReactiveModel, IDataCollection where T : class 54 | { 55 | protected readonly List _data = new List(); 56 | 57 | public IReadOnlyList Data => _data; 58 | 59 | IReadOnlyCollection IDataCollection.Data => _data; 60 | 61 | public void Add([NotNull] T item) 62 | { 63 | _data.Add(item); 64 | NotifyChanges(); 65 | } 66 | 67 | public void AddRange([ItemNotNull] IEnumerable items) 68 | { 69 | _data.AddRange(items); 70 | NotifyChanges(); 71 | } 72 | 73 | public void Remove(T item) 74 | { 75 | if (_data.Remove(item)) 76 | { 77 | NotifyChanges(); 78 | } 79 | } 80 | 81 | public void RemoveAll(Predicate match) 82 | { 83 | if (_data.RemoveAll(match) > 0) 84 | { 85 | NotifyChanges(); 86 | } 87 | } 88 | 89 | public void Clear() 90 | { 91 | _data.Clear(); 92 | NotifyChanges(); 93 | } 94 | 95 | public void Refresh() 96 | { 97 | NotifyChanges(); 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/IPresenter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Behc.Mvp.Presenters 5 | { 6 | public interface IPresenter 7 | { 8 | bool IsActive { get; } 9 | bool IsAnimating { get; } 10 | 11 | RectTransform RectTransform { get; } 12 | 13 | // Called exactly once, when presenter is created or registered (if loaded as part of scene), 14 | // this is especially important for object pools, as reused presenter is not initialized multiple times 15 | void Initialize(IPresenterMap presenterMap, PresenterUpdateKernel kernel); 16 | 17 | // Called before destroying GameObjects, most likely on unregister. 18 | void Destroy(); 19 | 20 | // Called every time a model is bound to presenter. Cannot be called again without calling Unbind() first. 21 | // 'prepareForAnimation' - if true, AnimateShow will be called somewhere in future to complete show process 22 | void Bind(object model, IPresenter parent, bool prepareForAnimation); 23 | 24 | // Called to unbind a model. No references should be held at this point. 25 | void Unbind(); 26 | 27 | // Called only if parent presenter supports animations and 'prepareForAnimation' was true during Bind() 28 | // Implementation *must* call onFinish when done (even if no animation was started). 29 | void AnimateShow(float startTime, Action onFinish); 30 | 31 | // Called only if parent presenter supports animations. 32 | // Implementation *must* call onFinish when done (even if no animation was started). 33 | void AnimateHide(float startTime, Action onFinish); 34 | 35 | // Called if parent presenter decides to interrupt transition and IsAnimating is true. 36 | // Implementation must finish any pending animations and call adequate onFinish before exiting this method. 37 | void AbortAnimations(); 38 | 39 | // Called when presenter can process user input, after all animations/transitions are done, and there is no blocking layers active. 40 | void Activate(); 41 | 42 | // Called before hide animations or Unbind(), or in case of activating some blocking layer. 43 | void Deactivate(); 44 | 45 | // Called on presenter request, during PresenterUpdateKernel's Update. 46 | // Request this update using PresenterUpdateKernel.RequestUpdate(this) 47 | // Important: Some methods (like Bind/Unbind) can only be called during this update 48 | void ScheduledUpdate(); 49 | 50 | // Called only from outside on demand 51 | // Steers the policy for what happens to the gameObject on unbind 52 | void SetUnbindPolicy(UnbindPolicy unbindPolicy); 53 | } 54 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Factories/SingleInstanceFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | using UnityEngine; 4 | using Object = UnityEngine.Object; 5 | 6 | namespace Behc.Mvp.Presenters.Factories 7 | { 8 | public class SingleInstanceFactory : IPresenterFactory 9 | { 10 | private GameObject _instance; 11 | private readonly Transform _container; 12 | 13 | private IPresenter _presenter; 14 | private int _refCount; 15 | 16 | public SingleInstanceFactory(GameObject instance, PresenterMap presenterMap, PresenterUpdateKernel updateKernel, Transform container) 17 | { 18 | _instance = instance; 19 | _container = container; 20 | 21 | _presenter = _instance.GetComponent(); 22 | _presenter.RectTransform.SetParent(_container, false); 23 | 24 | _presenter.Initialize(presenterMap, updateKernel); 25 | _instance.SetActive(false); 26 | } 27 | 28 | public IPresenter CreatePresenter(RectTransform parentTransform) 29 | { 30 | _refCount++; 31 | 32 | if (_presenter.RectTransform.parent != parentTransform) 33 | _presenter.RectTransform.SetParent(parentTransform, false); 34 | 35 | return _presenter; 36 | } 37 | 38 | public void DestroyPresenter(IPresenter presenter) 39 | { 40 | _refCount--; 41 | 42 | if (_refCount == 0) 43 | { 44 | if (_presenter.RectTransform.parent != _container) 45 | _presenter.RectTransform.SetParent(_container, false); 46 | 47 | _instance.SetActive(false); 48 | } 49 | } 50 | 51 | public void Dispose() 52 | { 53 | Object.Destroy(_instance); 54 | _instance = null; 55 | _presenter = null; 56 | } 57 | } 58 | 59 | public static class SingleInstanceFactoryExtensions 60 | { 61 | [MustUseReturnValue] 62 | public static IDisposable RegisterInstance(this PresenterMap presenterMap, GameObject instance, PresenterUpdateKernel updateKernel, RectTransform container) 63 | { 64 | return presenterMap.Register(new SingleInstanceFactory(instance, presenterMap, updateKernel, container)); 65 | } 66 | 67 | [MustUseReturnValue] 68 | public static IDisposable RegisterInstance(this PresenterMap presenterMap, GameObject instance, PresenterUpdateKernel updateKernel, RectTransform container, Func predicate) 69 | { 70 | return presenterMap.Register(new SingleInstanceFactory(instance, presenterMap, updateKernel, container), predicate); 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /Runtime/Navigation/NavigationBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using JetBrains.Annotations; 5 | 6 | namespace Behc.Navigation 7 | { 8 | public abstract class NavigableBase : INavigable 9 | { 10 | private List _stopDisposables; 11 | private List _disposables; 12 | private CancellationTokenSource _cancellation; 13 | 14 | protected virtual void OnStart() 15 | { 16 | } 17 | 18 | protected virtual void OnRestart(object parameters) 19 | { 20 | } 21 | 22 | protected virtual void OnStop() 23 | { 24 | } 25 | 26 | protected virtual void OnDispose(Action onComplete) 27 | { 28 | onComplete?.Invoke(); 29 | } 30 | 31 | protected void DisposeOnStop([NotNull] IDisposable disposable) 32 | { 33 | _stopDisposables ??= new List(); 34 | _stopDisposables.Add(disposable); 35 | } 36 | 37 | protected void AutoDispose([NotNull] IDisposable disposable) 38 | { 39 | _disposables ??= new List(); 40 | _disposables.Add(disposable); 41 | } 42 | 43 | protected CancellationToken CancelOnStop() 44 | { 45 | _cancellation ??= new CancellationTokenSource(); 46 | 47 | return _cancellation.Token; 48 | } 49 | 50 | void INavigable.Start() 51 | { 52 | OnStart(); 53 | } 54 | 55 | void INavigable.Restart(object parameters) 56 | { 57 | OnRestart(parameters); 58 | } 59 | 60 | void INavigable.Stop() 61 | { 62 | if (_cancellation != null) 63 | { 64 | _cancellation.Cancel(); 65 | _cancellation.Dispose(); 66 | _cancellation = null; 67 | } 68 | 69 | OnStop(); 70 | 71 | if (_stopDisposables != null) 72 | { 73 | foreach (IDisposable disposable in _stopDisposables) 74 | disposable.Dispose(); 75 | _stopDisposables.Clear(); 76 | } 77 | } 78 | 79 | void INavigable.LongDispose(Action onComplete) 80 | { 81 | OnDispose(Complete); 82 | 83 | void Complete() 84 | { 85 | if (_disposables != null) 86 | { 87 | foreach (IDisposable disposable in _disposables) 88 | disposable.Dispose(); 89 | _disposables.Clear(); 90 | } 91 | 92 | onComplete?.Invoke(); 93 | } 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /Runtime/Configuration/Loaders/AssetBundleScriptableConfiguratorLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Behc.Configuration.Loaders 5 | { 6 | //simple asset bundle loader, does not track any usage of a given bundle 7 | public class AssetBundleScriptableConfiguratorLoader : IConfiguratorLoader 8 | { 9 | public ConfiguratorStatus Status { get; private set; } 10 | 11 | public float Progress => _asyncOperation?.progress ?? 1.0f; 12 | 13 | private readonly AssetBundle _bundle; 14 | private readonly string _assetName; 15 | private readonly bool _canUnloadBundle; 16 | 17 | private AssetBundleRequest _asyncOperation; 18 | private IConfigurator _configurator; 19 | 20 | public AssetBundleScriptableConfiguratorLoader(AssetBundle bundle, string assetName, bool canUnloadBundle) 21 | { 22 | _bundle = bundle; 23 | _assetName = assetName; 24 | _canUnloadBundle = canUnloadBundle; 25 | 26 | Status = ConfiguratorStatus.UNLOADED; 27 | } 28 | 29 | public void Load(IDependencyResolver resolver, Action onComplete) 30 | { 31 | Debug.Assert(Status == ConfiguratorStatus.UNLOADED, $"Invalid status: '{Status}' for '{_bundle.name}:{_assetName}' scriptable configurator!"); 32 | 33 | void Finished(AsyncOperation _) 34 | { 35 | _configurator = (IConfigurator)_asyncOperation.asset; 36 | _asyncOperation = null; 37 | 38 | try 39 | { 40 | _configurator.Load(resolver); 41 | } 42 | catch (Exception e) 43 | { 44 | Debug.LogException(e); 45 | } 46 | 47 | Status = ConfiguratorStatus.LOADED; 48 | onComplete?.Invoke(); 49 | } 50 | 51 | Status = ConfiguratorStatus.LOADING; 52 | _asyncOperation = _bundle.LoadAssetAsync(_assetName); 53 | _asyncOperation.completed += Finished; 54 | } 55 | 56 | public void Unload(IDependencyResolver resolver, Action onComplete) 57 | { 58 | Debug.Assert(Status == ConfiguratorStatus.LOADED, $"Invalid status: '{Status}' for '{_bundle.name}:{_assetName}' scriptable configurator!"); 59 | 60 | try 61 | { 62 | _configurator.Unload(resolver); 63 | } 64 | catch (Exception e) 65 | { 66 | Debug.LogException(e); 67 | } 68 | 69 | _configurator = null; 70 | if (_canUnloadBundle) 71 | { 72 | _bundle.Unload(true); 73 | } 74 | 75 | Status = ConfiguratorStatus.UNLOADED; 76 | onComplete?.Invoke(); 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /Runtime/Configuration/ScriptableConfigurator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using JetBrains.Annotations; 4 | using UnityEngine; 5 | 6 | namespace Behc.Configuration 7 | { 8 | // [CreateAssetMenu(fileName = "ScriptableConfigurator", menuName = "Game/Configurator/ScriptableConfigurator", order = 0)] 9 | public class ScriptableConfigurator : ScriptableObject, IConfigurator 10 | { 11 | [SerializeField] private ScriptableConfigurator[] _subConfigurators; 12 | 13 | [NonSerialized] private List _disposables; 14 | 15 | void IConfigurator.Load(IDependencyResolver resolver) 16 | { 17 | MiniDiActivator.CallMethod(resolver, this, "OnLoad"); 18 | 19 | if (_subConfigurators != null) 20 | { 21 | foreach (IConfigurator sc in _subConfigurators) 22 | { 23 | sc.Load(resolver); 24 | } 25 | } 26 | } 27 | 28 | void IConfigurator.Unload(IDependencyResolver resolver) 29 | { 30 | if (_subConfigurators != null) 31 | { 32 | for (int i = _subConfigurators.Length; i > 0; i--) 33 | { 34 | IConfigurator sc = _subConfigurators[i - 1]; 35 | sc.Unload(resolver); 36 | } 37 | } 38 | 39 | MiniDiActivator.CallMethod(resolver, this, "OnUnload"); 40 | 41 | if (_disposables != null) 42 | { 43 | foreach (IDisposable disposable in _disposables) 44 | { 45 | disposable.Dispose(); 46 | } 47 | 48 | _disposables.Clear(); 49 | _disposables = null; 50 | } 51 | } 52 | 53 | protected void DisposeOnUnload([NotNull] IDisposable disposable) 54 | { 55 | _disposables ??= new List(); 56 | _disposables.Add(disposable); 57 | } 58 | 59 | #if UNITY_EDITOR 60 | private void OnEnable() 61 | { 62 | UnityEditor.EditorApplication.playModeStateChanged += EditorApplicationOnplayModeStateChanged; 63 | } 64 | 65 | private void OnDisable() 66 | { 67 | UnityEditor.EditorApplication.playModeStateChanged -= EditorApplicationOnplayModeStateChanged; 68 | } 69 | 70 | private void EditorApplicationOnplayModeStateChanged(UnityEditor.PlayModeStateChange obj) 71 | { 72 | if (obj == UnityEditor.PlayModeStateChange.EnteredEditMode) 73 | { 74 | _disposables?.Clear(); 75 | _disposables = null; 76 | 77 | OnEditorReset(); 78 | } 79 | } 80 | 81 | protected virtual void OnEditorReset() { } 82 | #endif 83 | } 84 | } -------------------------------------------------------------------------------- /Runtime/Navigation/NavigationUriResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Behc.Utils; 4 | using JetBrains.Annotations; 5 | 6 | namespace Behc.Navigation 7 | { 8 | //TODO: make it more generic, deep link should be able to do anything, not only navigation 9 | public class NavigationUriResolver 10 | { 11 | private static readonly char[] _splitPath = { '/' }; 12 | private static readonly char[] _splitQuery = { '?', '&', '=' }; 13 | 14 | private readonly Dictionary _navigationResolvers; 15 | 16 | public NavigationUriResolver() 17 | { 18 | _navigationResolvers = new Dictionary(); 19 | } 20 | 21 | [MustUseReturnValue] 22 | public IDisposable Register([NotNull] string navigableName, [NotNull] INavigationParametersResolver resolver) 23 | { 24 | _navigationResolvers.Add(navigableName, resolver); 25 | 26 | return new GenericDisposable(() => { _navigationResolvers.Remove(navigableName); }); 27 | } 28 | 29 | public bool FindNavigable(Uri uri, out string navigableName, out object parameters) 30 | { 31 | List pathList = new List(); 32 | Dictionary parametersList = new Dictionary(); 33 | 34 | string name = null; 35 | 36 | if (uri.LocalPath.Length > 1) 37 | { 38 | string[] pathParts = uri.LocalPath.Split(_splitPath, StringSplitOptions.RemoveEmptyEntries); 39 | 40 | int startingIndex = 0; 41 | if (pathParts.Length > 0 && pathParts[0] == "links") //TODO: make optional and configurable 42 | startingIndex++; 43 | 44 | if (pathParts.Length > startingIndex) 45 | { 46 | name = pathParts[startingIndex]; 47 | startingIndex++; 48 | } 49 | 50 | for (int i = startingIndex; i < pathParts.Length; i++) 51 | { 52 | pathList.Add(pathParts[i]); 53 | } 54 | } 55 | 56 | if (uri.Query.Length > 0) 57 | { 58 | string[] queryParts = uri.Query.Split(_splitQuery, StringSplitOptions.RemoveEmptyEntries); 59 | for (int i = 0; i < queryParts.Length / 2; i++) 60 | { 61 | parametersList.Add(queryParts[2 * i], queryParts[2 * i + 1]); 62 | } 63 | } 64 | 65 | if (!string.IsNullOrEmpty(name) && _navigationResolvers.TryGetValue(name, out var resolver)) 66 | { 67 | navigableName = name; 68 | parameters = resolver.FromUri(pathList, parametersList); 69 | return true; 70 | } 71 | 72 | navigableName = null; 73 | parameters = null; 74 | return false; 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /Samples~/DataPresentersGallery/DataPresentersGallerySampleInstaller.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using UnityEditor; 4 | using UnityEditor.Presets; 5 | using UnityEditor.SceneManagement; 6 | using UnityEngine; 7 | 8 | namespace DataPresentersGallerySample 9 | { 10 | [InitializeOnLoad] 11 | public static class DataPresentersGallerySampleInstaller 12 | { 13 | private const string _ROOT_SCENE = "Assets/DataPresentersGallery/RootScene/DataPresentersGalleryRootScene.unity"; 14 | private const string _ELEMENTS_SCENE = "Assets/DataPresentersGallery/ElementsScene/DataPresentersGalleryElementsScene.unity"; 15 | 16 | private const string _PACKAGE_NAME = "sample_gallery"; 17 | private const string _ASSET_PACKAGE_PATH = "Packages/com.behc.mvptoolkit/AssetPackages/sample_gallery.unitypackage"; 18 | 19 | static DataPresentersGallerySampleInstaller() 20 | { 21 | AssetDatabase.importPackageCompleted += OnImportPackageCompleted; 22 | 23 | if (IsSampleInstalled()) 24 | return; 25 | 26 | if (HasTextMeshProPackage() && HasTextMeshProEssentials()) 27 | { 28 | InstallAssetPackage(); 29 | } 30 | else 31 | { 32 | DataPresentersGallerySampleWindow.ShowWindow(); 33 | } 34 | } 35 | 36 | public static bool HasTextMeshProPackage() 37 | { 38 | #if SAMPLE_TEXTMESHPRO_PRESENT 39 | return true; 40 | #else 41 | return false; 42 | #endif 43 | } 44 | 45 | public static bool HasTextMeshProEssentials() 46 | { 47 | // taken from TMP code 48 | return File.Exists("Assets/TextMesh Pro/Resources/TMP Settings.asset"); 49 | } 50 | 51 | public static bool IsSampleInstalled() 52 | { 53 | return File.Exists(_ROOT_SCENE); 54 | } 55 | 56 | public static void InstallAssetPackage() 57 | { 58 | AssetDatabase.ImportPackage(_ASSET_PACKAGE_PATH, false); 59 | } 60 | 61 | private static void SetupScenes() 62 | { 63 | List scenes = new List(EditorBuildSettings.scenes); 64 | 65 | if (scenes.Find(i => i.path == _ROOT_SCENE) == null) 66 | { 67 | scenes.Add(new EditorBuildSettingsScene(_ROOT_SCENE, true)); 68 | } 69 | 70 | if (scenes.Find(i => i.path == _ELEMENTS_SCENE) == null) 71 | { 72 | scenes.Add(new EditorBuildSettingsScene(_ELEMENTS_SCENE, true)); 73 | } 74 | 75 | EditorBuildSettings.scenes = scenes.ToArray(); 76 | 77 | EditorSceneManager.OpenScene(_ROOT_SCENE); 78 | } 79 | 80 | private static void SetupLayers() 81 | { 82 | Object tagManager = AssetDatabase.LoadMainAssetAtPath("ProjectSettings/TagManager.asset"); 83 | Preset preset = (Preset)AssetDatabase.LoadMainAssetAtPath("Assets/TagManager.preset"); 84 | preset.ApplyTo(tagManager); 85 | } 86 | 87 | private static void OnImportPackageCompleted(string packageName) 88 | { 89 | if (packageName == _PACKAGE_NAME) 90 | { 91 | SetupScenes(); 92 | SetupLayers(); 93 | } 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Animations/ScaleAnimation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Behc.MiniTween; 3 | using Behc.MiniTween.Extensions; 4 | using UnityEngine; 5 | 6 | namespace Behc.Mvp.Animations 7 | { 8 | public class ScaleAnimation : IAnimator 9 | { 10 | private readonly ScaleAnimationOptions _options; 11 | private readonly RectTransform _transform; 12 | private readonly CanvasGroup _canvasGroup; 13 | 14 | private ITween _tweenFade; 15 | private ITween _tweenScale; 16 | 17 | public bool IsAnimating => _tweenFade != null || _tweenScale != null; 18 | 19 | public ScaleAnimation(ScaleAnimationOptions options, RectTransform transform, CanvasGroup canvasGroup) 20 | { 21 | _options = options; 22 | _transform = transform; 23 | _canvasGroup = canvasGroup; 24 | } 25 | 26 | public void Setup(bool prepareForAnimation) 27 | { 28 | _canvasGroup.alpha = prepareForAnimation ? _options.ShowAlphaStart : 1.0f; 29 | _transform.localScale = prepareForAnimation ? new Vector3(_options.ShowScaleStart, _options.ShowScaleStart, _options.ShowScaleStart) : Vector3.one; 30 | } 31 | 32 | public void AnimateShow(float startTime, Action onFinish) 33 | { 34 | if (startTime >= _options.ShowDuration || _options.ShowDuration <= 0) 35 | { 36 | _canvasGroup.alpha = 1.0f; 37 | _transform.localScale = Vector3.one; 38 | 39 | onFinish?.Invoke(); 40 | return; 41 | } 42 | 43 | ITweenSystem tweenSystem = _options.TweenProvider.GetInstance(); 44 | _tweenFade = _canvasGroup.AnimateAlpha(tweenSystem, 1, _options.ShowDuration); 45 | _tweenScale = _transform.AnimateScale(tweenSystem, Vector3.one, _options.ShowDuration); 46 | _tweenScale.SetEase(_options.ShowScaleCurve); 47 | 48 | _tweenScale.SetCompleteCallback(() => 49 | { 50 | _tweenFade = null; 51 | _tweenScale = null; 52 | onFinish?.Invoke(); 53 | }); 54 | 55 | _tweenFade.SetCurrentTime(startTime); 56 | _tweenScale.SetCurrentTime(startTime); 57 | } 58 | 59 | public void AnimateHide(float startTime, Action onFinish) 60 | { 61 | if (startTime >= _options.HideDuration || _options.HideDuration <= 0) 62 | { 63 | onFinish?.Invoke(); 64 | return; 65 | } 66 | 67 | ITweenSystem tweenSystem = _options.TweenProvider.GetInstance(); 68 | _tweenFade = _canvasGroup.AnimateAlpha(tweenSystem, _options.HideAlphaEnd, _options.HideDuration); 69 | _tweenScale = _transform.AnimateScale(tweenSystem, new Vector3(_options.HideScaleEnd, _options.HideScaleEnd, _options.HideScaleEnd), _options.HideDuration); 70 | _tweenScale.SetEase(_options.HideScaleCurve); 71 | 72 | _tweenScale.SetCompleteCallback(() => 73 | { 74 | _tweenFade = null; 75 | _tweenScale = null; 76 | onFinish?.Invoke(); 77 | }); 78 | 79 | _tweenFade.SetCurrentTime(startTime); 80 | _tweenScale.SetCurrentTime(startTime); 81 | } 82 | 83 | public void AbortAnimations() 84 | { 85 | _tweenFade?.Complete(); 86 | _tweenScale?.Complete(); 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Models/PopupMenuManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using UnityEngine; 5 | using UnityEngine.Assertions; 6 | 7 | namespace Behc.Mvp.Models 8 | { 9 | public class PopupMenuManager : ReactiveModel, IDataCollection 10 | { 11 | public enum Placement 12 | { 13 | PLACE_AT_CURSOR, 14 | RIGHT_OF_RECT, 15 | LEFT_OF_RECT, 16 | TOP_OF_RECT, 17 | BOTTOM_OF_RECT, 18 | } 19 | 20 | private class ItemType 21 | { 22 | public object Model; 23 | public Placement Placement; 24 | public Rect Rect; 25 | } 26 | 27 | private class Collection : IReadOnlyCollection 28 | { 29 | private readonly List _stack; 30 | 31 | public int Count => _stack.Count; 32 | 33 | public Collection(List stack) 34 | { 35 | _stack = stack; 36 | } 37 | 38 | public IEnumerator GetEnumerator() => _stack.Select(i => i.Model).GetEnumerator(); 39 | 40 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 41 | } 42 | 43 | public IReadOnlyCollection Data => _collection; 44 | 45 | private readonly List _items; 46 | private readonly Collection _collection; 47 | 48 | public PopupMenuManager() 49 | { 50 | _items = new List(16); 51 | _collection = new Collection(_items); 52 | } 53 | 54 | public void Add(object model) 55 | { 56 | Assert.IsNotNull(model); 57 | Assert.IsNull(_items.Find(i => i.Model == model)); 58 | 59 | _items.Add(new ItemType { Model = model, Placement = Placement.PLACE_AT_CURSOR }); 60 | NotifyChanges(); 61 | } 62 | 63 | public void Add(object model, Placement placement, Rect rect) 64 | { 65 | Assert.IsNotNull(model); 66 | Assert.IsNull(_items.Find(i => i.Model == model)); 67 | 68 | _items.Add(new ItemType { Model = model, Placement = placement, Rect = rect }); 69 | NotifyChanges(); 70 | } 71 | 72 | public void Remove(object model) 73 | { 74 | Assert.IsNotNull(model); 75 | Assert.IsNotNull(_items.Find(i => i.Model == model)); 76 | 77 | _items.RemoveAll(i => i.Model == model); 78 | NotifyChanges(); 79 | } 80 | 81 | public void RemoveAllAfter(object model) 82 | { 83 | Assert.IsNotNull(model); 84 | 85 | int index = _items.FindIndex(0, i => i.Model == model); 86 | if (index >= 0 && index < _items.Count - 1) 87 | { 88 | _items.RemoveRange(index + 1, _items.Count - index - 1); 89 | NotifyChanges(); 90 | } 91 | } 92 | 93 | public void RemoveAll() 94 | { 95 | _items.Clear(); 96 | NotifyChanges(); 97 | } 98 | 99 | public Placement GetItemPlacement(object model) 100 | { 101 | return _items.Find(i => i.Model == model)?.Placement ?? Placement.PLACE_AT_CURSOR; 102 | } 103 | 104 | public Rect GetItemRect(object model) 105 | { 106 | return _items.Find(i => i.Model == model)?.Rect ?? Rect.zero; 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Components/ViewRegion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Behc.Utils; 3 | using UnityEngine; 4 | 5 | namespace Behc.Mvp.Components 6 | { 7 | public class ViewRegion : MonoBehaviour 8 | { 9 | public Rect ClipRect 10 | { 11 | get 12 | { 13 | UpdateRects(); 14 | return _intersectionRect; 15 | } 16 | } 17 | 18 | private Rect _worldRect = Rect.zero; 19 | private Rect _intersectionRect = Rect.zero; 20 | private ViewRegion _parentRegion; 21 | 22 | private void OnTransformParentChanged() 23 | { 24 | UpdateParentRegion(); 25 | } 26 | 27 | private void OnDrawGizmosSelected() 28 | { 29 | Gizmos.color = Color.cyan; 30 | Gizmos.DrawLine(new Vector3(_worldRect.xMin, _worldRect.yMin), new Vector3(_worldRect.xMax, _worldRect.yMin)); 31 | Gizmos.DrawLine(new Vector3(_worldRect.xMax, _worldRect.yMin), new Vector3(_worldRect.xMax, _worldRect.yMax)); 32 | Gizmos.DrawLine(new Vector3(_worldRect.xMax, _worldRect.yMax), new Vector3(_worldRect.xMin, _worldRect.yMax)); 33 | Gizmos.DrawLine(new Vector3(_worldRect.xMin, _worldRect.yMax), new Vector3(_worldRect.xMin, _worldRect.yMin)); 34 | 35 | Gizmos.color = _intersectionRect.width > 0 && _intersectionRect.height > 0 ? Color.green : Color.red; 36 | Gizmos.DrawLine(new Vector3(_intersectionRect.xMin, _intersectionRect.yMin), new Vector3(_intersectionRect.xMax, _intersectionRect.yMin)); 37 | Gizmos.DrawLine(new Vector3(_intersectionRect.xMax, _intersectionRect.yMin), new Vector3(_intersectionRect.xMax, _intersectionRect.yMax)); 38 | Gizmos.DrawLine(new Vector3(_intersectionRect.xMax, _intersectionRect.yMax), new Vector3(_intersectionRect.xMin, _intersectionRect.yMax)); 39 | Gizmos.DrawLine(new Vector3(_intersectionRect.xMin, _intersectionRect.yMax), new Vector3(_intersectionRect.xMin, _intersectionRect.yMin)); 40 | } 41 | 42 | private void UpdateRects() 43 | { 44 | RectTransform rt = (RectTransform) transform; 45 | 46 | Rect rect = rt.rect; 47 | 48 | Vector3 lMin = new Vector3(rect.xMin, rect.yMin, 0); 49 | Vector3 lMax = new Vector3(rect.xMax, rect.yMax, 0); 50 | 51 | Vector3 wMin = rt.TransformPoint(lMin); 52 | Vector3 wMax = rt.TransformPoint(lMax); 53 | 54 | _worldRect = Rect.MinMaxRect(wMin.x, wMin.y, wMax.x, wMax.y); 55 | 56 | if (_parentRegion.IsNotNull()) 57 | { 58 | _parentRegion.UpdateRects(); 59 | _intersectionRect = Rect.MinMaxRect( 60 | Math.Max(_worldRect.xMin, _parentRegion._intersectionRect.xMin), 61 | Math.Max(_worldRect.yMin, _parentRegion._intersectionRect.yMin), 62 | Math.Min(_worldRect.xMax, _parentRegion._intersectionRect.xMax), 63 | Math.Min(_worldRect.yMax, _parentRegion._intersectionRect.yMax)); 64 | } 65 | else 66 | { 67 | _intersectionRect = _worldRect; 68 | } 69 | } 70 | 71 | private void UpdateParentRegion() 72 | { 73 | _parentRegion = null; 74 | Transform tr = transform.parent; 75 | while (tr != null) 76 | { 77 | _parentRegion = tr.GetComponent(); 78 | if (_parentRegion != null) 79 | { 80 | _parentRegion.UpdateParentRegion(); 81 | break; 82 | } 83 | 84 | tr = tr.parent; 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/DataStackPresenter.cs: -------------------------------------------------------------------------------- 1 | using Behc.Mvp.Models; 2 | using Behc.Mvp.Utils; 3 | using UnityEngine; 4 | 5 | namespace Behc.Mvp.Presenters 6 | { 7 | public class DataStackPresenter : AnimatedPresenterBase 8 | { 9 | // TODO: migrate to Curtain or create generic event for presenter changes 10 | [SerializeField] protected GameObject _clickToCloseInfo; 11 | 12 | public override void Bind(object model, IPresenter parent, bool prepareForAnimation) 13 | { 14 | base.Bind(model, parent, prepareForAnimation); 15 | 16 | if (_curtain != null) 17 | { 18 | DisposeOnUnbind(_curtain.OnTrigger.Subscribe(CurtainClicked)); 19 | 20 | if (prepareForAnimation && _items.Count > 0) 21 | { 22 | _curtain.Show(_items.Count * _sortingStep); 23 | } 24 | else 25 | { 26 | _curtain.Setup(_items.Count > 0, _items.Count * _sortingStep); 27 | } 28 | } 29 | } 30 | 31 | protected override void OnActivate() 32 | { 33 | if (_items.Count > 0) 34 | { 35 | ItemDesc topLevel = _items[_items.Count - 1]; 36 | if (topLevel.State == ItemState.READY) 37 | { 38 | topLevel.Presenter.Activate(); 39 | topLevel.Active = true; 40 | } 41 | } 42 | } 43 | 44 | protected override void OnDeactivate() 45 | { 46 | if (_items.Count > 0) 47 | { 48 | ItemDesc topLevel = _items[_items.Count - 1]; 49 | if (topLevel.Active) 50 | { 51 | topLevel.Presenter.Deactivate(); 52 | topLevel.Active = false; 53 | } 54 | } 55 | } 56 | 57 | protected override void UpdateContent() 58 | { 59 | int oldCount = _items.Count; 60 | base.UpdateContent(); 61 | 62 | for (int index = 0; index < _items.Count - 1; index++) 63 | { 64 | ItemDesc desc = _items[index]; 65 | if (desc.Active) 66 | { 67 | desc.Presenter.Deactivate(); 68 | desc.Active = false; 69 | } 70 | } 71 | 72 | if (_items.Count > 0 && IsActive) 73 | { 74 | ItemDesc topLevel = _items[_items.Count - 1]; 75 | if (!topLevel.Active && topLevel.State == ItemState.READY) 76 | { 77 | topLevel.Presenter.Activate(); 78 | topLevel.Active = true; 79 | } 80 | } 81 | 82 | if (_curtain != null) 83 | { 84 | if (_items.Count == 0) 85 | { 86 | if (oldCount > 0) 87 | _curtain.Hide(); 88 | } 89 | else 90 | { 91 | if (oldCount == 0) 92 | _curtain.Show(_items.Count * _sortingStep); 93 | else if (oldCount != _items.Count) 94 | _curtain.Switch(_items.Count * _sortingStep, oldCount * _sortingStep); 95 | } 96 | } 97 | 98 | if (_clickToCloseInfo != null) 99 | { 100 | _clickToCloseInfo.SetActive(_model.CanDefaultClose()); 101 | } 102 | } 103 | 104 | private void CurtainClicked() 105 | { 106 | _model.TryRemoveTopLevel(); 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/PresenterMap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Behc.Mvp.Presenters.Factories; 4 | using Behc.Utils; 5 | using JetBrains.Annotations; 6 | 7 | namespace Behc.Mvp.Presenters 8 | { 9 | public class PresenterMap : IPresenterMap 10 | { 11 | private class MapItem 12 | { 13 | public IPresenterFactory DefaultFactory; 14 | public List<(IPresenterFactory factory, Func predicate)> SpecializedFactories; 15 | } 16 | 17 | private readonly IPresenterMap _parentMap; 18 | private Dictionary _map; 19 | 20 | public PresenterMap(IPresenterMap parentMap) 21 | { 22 | _parentMap = parentMap; 23 | } 24 | 25 | [MustUseReturnValue] 26 | public IDisposable Register(IPresenterFactory factory) 27 | { 28 | return AddDefaultFactory(typeof(T), factory); 29 | } 30 | 31 | [MustUseReturnValue] 32 | public IDisposable Register(IPresenterFactory factory, Func predicate) 33 | { 34 | return AddPredicatedFactory(typeof(T), factory, obj => predicate((T)obj)); 35 | } 36 | 37 | public IPresenterFactory TryGetPresenterFactory(object model) 38 | { 39 | if (_map != null && _map.TryGetValue(model.GetType(), out MapItem item)) 40 | { 41 | if (item.SpecializedFactories != null) 42 | { 43 | foreach ((IPresenterFactory factory, Func predicate) in item.SpecializedFactories) 44 | { 45 | if (predicate(model)) 46 | { 47 | return factory; 48 | } 49 | } 50 | } 51 | 52 | return item.DefaultFactory; 53 | } 54 | 55 | return _parentMap?.TryGetPresenterFactory(model); 56 | } 57 | 58 | private IDisposable AddDefaultFactory(Type modelType, IPresenterFactory presenterFactory) 59 | { 60 | MapItem mapItem = GetOrCreateMapItem(modelType); 61 | 62 | if (mapItem.DefaultFactory != null) 63 | throw new Exception($"Default factory for model '{modelType.Name}' already exist!"); 64 | 65 | mapItem.DefaultFactory = presenterFactory; 66 | return new GenericDisposable(() => 67 | { 68 | presenterFactory.Dispose(); 69 | mapItem.DefaultFactory = null; 70 | }); 71 | } 72 | 73 | private IDisposable AddPredicatedFactory(Type modelType, IPresenterFactory presenterFactory, Func wrappedPredicate) 74 | { 75 | MapItem mapItem = GetOrCreateMapItem(modelType); 76 | mapItem.SpecializedFactories ??= new List<(IPresenterFactory factory, Func predicate)>(); 77 | 78 | var tuple = (presenterFactory, wrappedPredicate); 79 | mapItem.SpecializedFactories.Add(tuple); 80 | 81 | return new GenericDisposable(() => 82 | { 83 | presenterFactory.Dispose(); 84 | mapItem.SpecializedFactories.Remove(tuple); 85 | }); 86 | } 87 | 88 | private MapItem GetOrCreateMapItem(Type modelType) 89 | { 90 | _map ??= new Dictionary(); 91 | 92 | if (_map.TryGetValue(modelType, out MapItem mapItem)) 93 | return mapItem; 94 | 95 | mapItem = new MapItem(); 96 | _map.Add(modelType, mapItem); 97 | 98 | return mapItem; 99 | } 100 | } 101 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Components/FadeCurtain.cs: -------------------------------------------------------------------------------- 1 | using Behc.MiniTween; 2 | using Behc.MiniTween.Extensions; 3 | using Behc.Utils; 4 | using UnityEngine; 5 | using UnityEngine.Assertions; 6 | 7 | namespace Behc.Mvp.Components 8 | { 9 | public class FadeCurtain : Curtain 10 | { 11 | #pragma warning disable CS0649 12 | [SerializeField] private AbstractProvider _tweenProvider; 13 | [SerializeField] private CanvasGroup _mainGroup; 14 | [SerializeField] private Canvas _mainCanvas; 15 | 16 | [SerializeField] private CanvasGroup _auxGroup; 17 | [SerializeField] private Canvas _auxCanvas; 18 | 19 | [SerializeField] [Range(1.0f / 255.0f, 1.0f)] 20 | private float _alpha = 0.5f; 21 | 22 | [SerializeField] private float _fadeDuration = 0.5f; 23 | #pragma warning restore CS0649 24 | 25 | private ITween _tween; 26 | 27 | private void OnDisable() 28 | { 29 | _tween?.Kill(); 30 | _tween = null; 31 | } 32 | 33 | public override void Setup(bool visible, int order) 34 | { 35 | _mainGroup.gameObject.SetActive(visible); 36 | _auxGroup.gameObject.SetActive(false); 37 | 38 | if (visible) 39 | { 40 | Assert.IsTrue(_mainGroup.gameObject.activeSelf); 41 | 42 | _mainGroup.alpha = _alpha; 43 | _mainCanvas.sortingOrder = order - 1; 44 | } 45 | } 46 | 47 | public override void Show(int order) 48 | { 49 | _tween?.Kill(); 50 | 51 | _mainGroup.gameObject.SetActive(true); 52 | _auxGroup.gameObject.SetActive(false); 53 | 54 | Assert.IsTrue(_mainGroup.gameObject.activeSelf); 55 | 56 | _mainGroup.alpha = 0; 57 | _mainCanvas.sortingOrder = order - 1; 58 | 59 | _tween = _mainGroup.AnimateAlpha(_tweenProvider.GetInstance(), _alpha, _fadeDuration); 60 | _tween.SetCompleteCallback(() => _tween = null); 61 | } 62 | 63 | public override void Switch(int newOrder, int previousOrder) 64 | { 65 | //TODO: check for same order parameters, avoid redundant animation resets 66 | _tween?.Kill(); 67 | 68 | _mainGroup.gameObject.SetActive(true); 69 | _auxGroup.gameObject.SetActive(true); 70 | 71 | Assert.IsTrue(_mainGroup.gameObject.activeSelf); 72 | Assert.IsTrue(_auxGroup.gameObject.activeSelf); 73 | 74 | _mainGroup.alpha = 0; 75 | _mainCanvas.sortingOrder = newOrder - 1; 76 | 77 | _auxGroup.alpha = _alpha; 78 | _auxCanvas.sortingOrder = previousOrder - 1; 79 | 80 | _tween = _auxGroup.AnimateAlpha(_tweenProvider.GetInstance(), 0, _fadeDuration); 81 | _tween.SetUpdateCallback(() => 82 | { 83 | float cs = _auxGroup.alpha; 84 | _mainGroup.alpha = (_alpha - cs) / (1.0f - cs); 85 | }); 86 | _tween.SetCompleteCallback(() => 87 | { 88 | _auxGroup.gameObject.SetActive(false); 89 | _tween = null; 90 | }); 91 | } 92 | 93 | public override void Hide() 94 | { 95 | _tween?.Kill(); 96 | 97 | _mainGroup.gameObject.SetActive(true); 98 | _auxGroup.gameObject.SetActive(false); 99 | 100 | Assert.IsTrue(_mainGroup.gameObject.activeSelf); 101 | 102 | _tween = _mainGroup.AnimateAlpha(_tweenProvider.GetInstance(), 0, _fadeDuration); 103 | _tween.SetCompleteCallback(() => 104 | { 105 | _mainGroup.gameObject.SetActive(false); 106 | _tween = null; 107 | }); 108 | } 109 | } 110 | } -------------------------------------------------------------------------------- /Documentation~/index.md: -------------------------------------------------------------------------------- 1 | ## About MvpToolkit 2 | 3 | This project started as few utility elements for MVP (Model-View-Presenter) architecture, adapted for Unity needs. 4 | Now, it contains multiple components that extends beyond this one purpose, but all contributes to the main goal: help with game/ui architecture setup. 5 | I kept the name, but it's more Minimal-Viable-Product-Toolkit now. 6 | 7 | #### Core concepts 8 | - Everything can be customized/expanded/replaced 9 | - No external dependencies (dependencies like UniRx or Zenject can be used with MvpToolkit but are not required) 10 | - No globals/statics/singletons 11 | 12 | #### Recommended for 13 | - UI heavy games (lots of windows and panels with complex navigation between them) 14 | 15 | #### Not recommended for 16 | - Games with very little UI (only main menu or some HUD) 17 | - Use for elements other than UI 18 | 19 | ## Components 20 | 21 | ### Mvp (Model-View-Presenter) 22 | 23 | Core component with all classes required for Mvp pattern and many helpers and generics 24 | to keep boilerplate code to minimum. 25 | 26 | [Read more](./mvp.md) 27 | 28 | ### Configuration 29 | 30 | Optional component to streamline process of registration new elements when game (or its part) is loaded. 31 | 32 | [Read more](./configuration.md) 33 | 34 | ### Navigation 35 | 36 | Optional component with application side navigation. 37 | 38 | [Read more](./navigation.md) 39 | 40 | ### MiniTween 41 | 42 | Very simple tweening engine, created mostly because there is no official DOTween UPM package to depend on. 43 | It is used in a few parts of Mvp component for animating transitions. 44 | 45 | [Read more](./tween.md) 46 | 47 | ## Getting started 48 | 49 | Minimal hello-world style game, requires a scene with PresenterKernel, DataSlotPresenter and some panel to actually present something to user. 50 | 51 | // HelloWorldSceneRoot.cs 52 | public class SampleScene : MonoBehaviour 53 | { 54 | // those elements should be added somewhere in scene 55 | [SerializeField] private PresenterUpdateKernel _updateKernel; 56 | [SerializeField] private RectTransform _container; //for inactive panels 57 | [SerializeField] private DataSlotPresenter _mainPanelPresenter; //top-most slot, where we can put some panels 58 | 59 | // this is example panel, normally it would be defined in different scene or available as a prefab 60 | [SerializeField] private HelloWorldPresenter _helloWorldPresenter; 61 | 62 | // this is part of root configuration, you need some top level presenters to show anything 63 | private readonly PresenterMap _rootPresenterMap = new PresenterMap(null); 64 | private readonly DataSlot _mainPanel = new DataSlot(); 65 | 66 | private readonly HelloWorld _helloWorld = new HelloWorld(); 67 | 68 | private void Start() 69 | { 70 | // initialize some root element, so we can use it to present our own data 71 | _updateKernel.InitializePresenters(kernel => 72 | { 73 | _mainPanelPresenter.Initialize(_rootPresenterMap, kernel); 74 | _mainPanelPresenter.Bind(_mainPanel, null, false); 75 | _mainPanelPresenter.Activate(); 76 | } 77 | 78 | // link data of type HelloWorld to use HelloWorldPresenter as a single object that is already in scene 79 | // this would be normally during configuration phase i.e. when scene is loaded 80 | _rootPresenterMap.RegisterInstance(_helloWorldPresenter.gameObject, _container, _updateKernel); 81 | 82 | // in this example panel is set once, but this can be changed at runtime i.e. using navigation system 83 | _mainPanel.Data = _helloWorld; 84 | } 85 | } 86 | 87 | // HelloWorld.cs 88 | public class HelloWorld {} 89 | 90 | // HelloWorldPresenter.cs 91 | public class HelloWorldPresenter : PanelBase {} 92 | 93 | For more examples, install samples from package. 94 | -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/Factories/PooledFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using JetBrains.Annotations; 4 | using UnityEngine; 5 | using Object = UnityEngine.Object; 6 | 7 | namespace Behc.Mvp.Presenters.Factories 8 | { 9 | public class PooledFactory : IPresenterFactory 10 | { 11 | private readonly GameObject _prefab; 12 | private readonly PresenterMap _presenterMap; 13 | private readonly PresenterUpdateKernel _updateKernel; 14 | private readonly Transform _container; 15 | private readonly List _unused = new List(); 16 | private readonly int _maximumPoolSize; 17 | 18 | public PooledFactory(GameObject prefab, PresenterMap presenterMap, PresenterUpdateKernel updateKernel, Transform container, int initialPoolSize = 0, int maximumPoolSize = int.MaxValue) 19 | { 20 | _prefab = prefab; 21 | _presenterMap = presenterMap; 22 | _updateKernel = updateKernel; 23 | _container = container; 24 | _maximumPoolSize = maximumPoolSize; 25 | 26 | //TODO: this doesn't work with LocalPresenterMap 27 | for (int i = 0; i < initialPoolSize; i++) 28 | _unused.Add(CreateNewObject(_container)); 29 | } 30 | 31 | public IPresenter CreatePresenter(RectTransform parentTransform) 32 | { 33 | if (_unused.Count > 0) 34 | { 35 | IPresenter presenter = _unused[_unused.Count - 1]; 36 | _unused.RemoveAt(_unused.Count - 1); 37 | 38 | if (presenter.RectTransform.parent != parentTransform) 39 | presenter.RectTransform.SetParent(parentTransform, false); 40 | 41 | return presenter; 42 | } 43 | 44 | return CreateNewObject(parentTransform); 45 | } 46 | 47 | public void DestroyPresenter(IPresenter presenter) 48 | { 49 | if (_unused.Count >= _maximumPoolSize) 50 | { 51 | presenter.Destroy(); 52 | Object.Destroy(presenter.RectTransform.gameObject); 53 | return; 54 | } 55 | 56 | if (presenter.RectTransform.parent != _container) 57 | presenter.RectTransform.SetParent(_container, false); 58 | 59 | _unused.Add(presenter); 60 | } 61 | 62 | public void Dispose() 63 | { 64 | foreach (IPresenter presenter in _unused) 65 | { 66 | presenter.Destroy(); 67 | Object.Destroy(presenter.RectTransform.gameObject); 68 | } 69 | } 70 | 71 | private IPresenter CreateNewObject(Transform container) 72 | { 73 | GameObject instance = Object.Instantiate(_prefab, container, false); 74 | IPresenter presenter = instance.GetComponent(); 75 | presenter.Initialize(_presenterMap, _updateKernel); 76 | instance.SetActive(false); 77 | 78 | return presenter; 79 | } 80 | } 81 | 82 | public static class PooledFactoryExtensions 83 | { 84 | [MustUseReturnValue] 85 | public static IDisposable RegisterPool(this PresenterMap presenterMap, GameObject prefab, PresenterUpdateKernel updateKernel, RectTransform container, int initialPoolSize = 0, int maximumPoolSize = int.MaxValue) 86 | { 87 | return presenterMap.Register(new PooledFactory(prefab, presenterMap, updateKernel, container, initialPoolSize, maximumPoolSize)); 88 | } 89 | 90 | [MustUseReturnValue] 91 | public static IDisposable RegisterPool(this PresenterMap presenterMap, GameObject prefab, PresenterUpdateKernel updateKernel, RectTransform container, Func predicate, int initialPoolSize = 0, int maximumPoolSize = int.MaxValue) 92 | { 93 | return presenterMap.Register(new PooledFactory(prefab, presenterMap, updateKernel, container, initialPoolSize, maximumPoolSize), predicate); 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Presenters/PresenterUpdateKernel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace Behc.Mvp.Presenters 6 | { 7 | [DefaultExecutionOrder(1000)] 8 | public class PresenterUpdateKernel : MonoBehaviour 9 | { 10 | public bool UpdateLoop { get; private set; } 11 | 12 | #if BEHC_MVPTOOLKIT_VERBOSE 13 | public static int Counter = 0; 14 | #endif 15 | 16 | private class PresenterItem 17 | { 18 | public IPresenter Presenter; 19 | public PresenterItem Parent; 20 | public List Children; 21 | 22 | public bool RequestedUpdate; 23 | public bool ChildRequestedUpdate; 24 | } 25 | 26 | private readonly List _rootElements = new List(); 27 | private readonly Dictionary _elementsMap = new Dictionary(); 28 | 29 | public void RegisterPresenter(IPresenter presenter, IPresenter parent) 30 | { 31 | if (parent == null) 32 | { 33 | PresenterItem item = new PresenterItem { Presenter = presenter }; 34 | _rootElements.Add(item); 35 | _elementsMap.Add(presenter, item); 36 | } 37 | else 38 | { 39 | PresenterItem parentItem = _elementsMap[parent]; 40 | if (parentItem.Children == null) 41 | parentItem.Children = new List(); 42 | 43 | PresenterItem item = new PresenterItem 44 | { 45 | Presenter = presenter, 46 | Parent = parentItem, 47 | }; 48 | 49 | parentItem.Children.Add(item); 50 | _elementsMap.Add(presenter, item); 51 | } 52 | } 53 | 54 | public void UnregisterPresenter(IPresenter presenter) 55 | { 56 | PresenterItem item = _elementsMap[presenter]; 57 | if (item.Parent != null) 58 | { 59 | item.Parent.Children.Remove(item); 60 | } 61 | else 62 | { 63 | _rootElements.Remove(item); 64 | } 65 | 66 | _elementsMap.Remove(presenter); 67 | 68 | if (item.Children != null && item.Children.Count > 0) 69 | throw new Exception("unregister non empty presenter!"); 70 | } 71 | 72 | public void RequestUpdate(IPresenter presenter) 73 | { 74 | PresenterItem item = _elementsMap[presenter]; 75 | item.RequestedUpdate = true; 76 | 77 | PresenterItem parent = item.Parent; 78 | while (parent != null) 79 | { 80 | parent.ChildRequestedUpdate = true; 81 | parent = parent.Parent; 82 | } 83 | } 84 | 85 | public void InitializePresenters(Action initCallback) 86 | { 87 | UpdateLoop = true; 88 | initCallback?.Invoke(this); 89 | UpdateLoop = false; 90 | } 91 | 92 | private void Update() 93 | { 94 | UpdateLoop = true; 95 | 96 | foreach (PresenterItem item in _rootElements) 97 | { 98 | UpdateItem(item); 99 | } 100 | 101 | UpdateLoop = false; 102 | 103 | #if BEHC_MVPTOOLKIT_VERBOSE 104 | Counter++; 105 | #endif 106 | } 107 | 108 | private void UpdateItem(PresenterItem item) 109 | { 110 | bool updateSelf = item.RequestedUpdate; 111 | bool updateChildren = item.ChildRequestedUpdate; 112 | item.RequestedUpdate = false; 113 | item.ChildRequestedUpdate = false; 114 | 115 | if (updateSelf) 116 | item.Presenter.ScheduledUpdate(); 117 | 118 | if (updateChildren && item.Children != null) 119 | { 120 | foreach (PresenterItem child in item.Children) 121 | { 122 | UpdateItem(child); 123 | } 124 | } 125 | } 126 | } 127 | } -------------------------------------------------------------------------------- /Runtime/Configuration/Loaders/AddressableSceneConfiguratorLoader.cs: -------------------------------------------------------------------------------- 1 | #if BEHC_MVPTOOLKIT_ADDRESSABLES 2 | using System; 3 | using UnityEngine; 4 | using UnityEngine.AddressableAssets; 5 | using UnityEngine.ResourceManagement.AsyncOperations; 6 | using UnityEngine.ResourceManagement.ResourceProviders; 7 | using UnityEngine.SceneManagement; 8 | 9 | namespace Behc.Configuration.Loaders 10 | { 11 | public class AddressableSceneConfiguratorLoader : IConfiguratorLoader 12 | { 13 | public ConfiguratorStatus Status { get; private set; } 14 | 15 | public float Progress => _handle.IsValid() ? _handle.PercentComplete : 1.0f; 16 | 17 | private readonly object _key; 18 | private AsyncOperationHandle _handle; 19 | private readonly bool _removeProxyObjects; 20 | 21 | public AddressableSceneConfiguratorLoader(object key, bool removeProxyObjects = true) 22 | { 23 | _key = key; 24 | _removeProxyObjects = removeProxyObjects; 25 | Status = ConfiguratorStatus.UNLOADED; 26 | } 27 | 28 | public void Load(IDependencyResolver resolver, Action onComplete) 29 | { 30 | Debug.Assert(Status == ConfiguratorStatus.UNLOADED, $"Invalid status: '{Status}' for '{_key}' scene!"); 31 | 32 | void Finished(AsyncOperationHandle obj) 33 | { 34 | Status = ConfiguratorStatus.LOADED; 35 | 36 | bool rootElementFound = false; 37 | Scene scene = _handle.Result.Scene; 38 | foreach (GameObject rootObj in scene.GetRootGameObjects()) 39 | { 40 | IConfigurator root = rootObj.GetComponent(); 41 | if (root == null) 42 | continue; 43 | 44 | rootElementFound = true; 45 | try 46 | { 47 | root.Load(resolver); 48 | } 49 | catch (Exception e) 50 | { 51 | Debug.LogException(e); 52 | } 53 | } 54 | 55 | if (!rootElementFound) 56 | Debug.LogError($"Missing scene configurator object for: '{scene.name}'"); 57 | 58 | //cleanup in 2nd pass - some root object could be reparented during root.Load() 59 | if (_removeProxyObjects) 60 | { 61 | foreach (GameObject rootObj in scene.GetRootGameObjects()) 62 | { 63 | IConfigurator root = rootObj.GetComponent(); 64 | if (root == null) 65 | { 66 | UnityEngine.Object.Destroy(rootObj); 67 | } 68 | } 69 | } 70 | 71 | onComplete?.Invoke(); 72 | } 73 | 74 | Status = ConfiguratorStatus.LOADING; 75 | _handle = Addressables.LoadSceneAsync(_key, LoadSceneMode.Additive); 76 | _handle.Completed += Finished; 77 | } 78 | 79 | public void Unload(IDependencyResolver resolver, Action onComplete) 80 | { 81 | Debug.Assert(Status == ConfiguratorStatus.LOADED, $"Invalid status: '{Status}' for '{_key}' scene!"); 82 | 83 | Scene scene = _handle.Result.Scene; 84 | foreach (GameObject rootObj in scene.GetRootGameObjects()) 85 | { 86 | try 87 | { 88 | IConfigurator root = rootObj.GetComponent(); 89 | root?.Unload(resolver); 90 | } 91 | catch (Exception e) 92 | { 93 | Debug.LogException(e); 94 | } 95 | } 96 | 97 | Status = ConfiguratorStatus.UNLOADING; 98 | 99 | Addressables.UnloadSceneAsync(_handle.Result).Completed += h => 100 | { 101 | Status = ConfiguratorStatus.UNLOADED; 102 | _handle = default; 103 | onComplete?.Invoke(); 104 | }; 105 | } 106 | } 107 | } 108 | #endif -------------------------------------------------------------------------------- /Samples~/SimpleGame/SimpleGameSampleInstaller.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using UnityEditor; 4 | using UnityEditor.Presets; 5 | using UnityEditor.SceneManagement; 6 | using UnityEngine; 7 | 8 | namespace DataPresentersGallerySample 9 | { 10 | [InitializeOnLoad] 11 | public static class SimpleGameSampleInstaller 12 | { 13 | private const string _PRELOADER_SCENE = "Assets/SimpleGame/PreloaderScene/SimpleGamePreloaderScene.unity"; 14 | private const string _ROOT_SCENE = "Assets/SimpleGame/RootScene/SimpleGameRootScene.unity"; 15 | private const string _LOBBY_SCENE = "Assets/SimpleGame/LobbyScene/SimpleGameLobbyScene.unity"; 16 | private const string _GAMEPLAY_SCENE = "Assets/SimpleGame/GameplayScene/SimpleGameGameplayScene.unity"; 17 | private const string _RANKING_SCENE = "Assets/SimpleGame/RankingScene/SimpleGameRankingScene.unity"; 18 | 19 | private const string _PACKAGE_NAME = "simple_game"; 20 | private const string _ASSET_PACKAGE_PATH = "Packages/com.behc.mvptoolkit/AssetPackages/simple_game.unitypackage"; 21 | 22 | static SimpleGameSampleInstaller() 23 | { 24 | AssetDatabase.importPackageCompleted += OnImportPackageCompleted; 25 | 26 | if (IsSampleInstalled()) 27 | return; 28 | 29 | if (HasTextMeshProPackage() && HasTextMeshProEssentials()) 30 | { 31 | InstallAssetPackage(); 32 | } 33 | else 34 | { 35 | SimpleGameSampleWindow.ShowWindow(); 36 | } 37 | } 38 | 39 | public static bool HasTextMeshProPackage() 40 | { 41 | #if SAMPLE_TEXTMESHPRO_PRESENT 42 | return true; 43 | #else 44 | return false; 45 | #endif 46 | } 47 | 48 | public static bool HasTextMeshProEssentials() 49 | { 50 | // taken from TMP code 51 | return File.Exists("Assets/TextMesh Pro/Resources/TMP Settings.asset"); 52 | } 53 | 54 | public static bool IsSampleInstalled() 55 | { 56 | return File.Exists(_ROOT_SCENE); 57 | } 58 | 59 | public static void InstallAssetPackage() 60 | { 61 | AssetDatabase.ImportPackage(_ASSET_PACKAGE_PATH, false); 62 | } 63 | 64 | private static void SetupScenes() 65 | { 66 | List scenes = new List(EditorBuildSettings.scenes); 67 | 68 | if (scenes.Find(i => i.path == _PRELOADER_SCENE) == null) 69 | { 70 | scenes.Add(new EditorBuildSettingsScene(_PRELOADER_SCENE, true)); 71 | } 72 | 73 | if (scenes.Find(i => i.path == _ROOT_SCENE) == null) 74 | { 75 | scenes.Add(new EditorBuildSettingsScene(_ROOT_SCENE, true)); 76 | } 77 | 78 | if (scenes.Find(i => i.path == _LOBBY_SCENE) == null) 79 | { 80 | scenes.Add(new EditorBuildSettingsScene(_LOBBY_SCENE, true)); 81 | } 82 | 83 | if (scenes.Find(i => i.path == _GAMEPLAY_SCENE) == null) 84 | { 85 | scenes.Add(new EditorBuildSettingsScene(_GAMEPLAY_SCENE, true)); 86 | } 87 | 88 | if (scenes.Find(i => i.path == _RANKING_SCENE) == null) 89 | { 90 | scenes.Add(new EditorBuildSettingsScene(_RANKING_SCENE, true)); 91 | } 92 | 93 | EditorBuildSettings.scenes = scenes.ToArray(); 94 | 95 | EditorSceneManager.OpenScene(_PRELOADER_SCENE); 96 | } 97 | 98 | private static void SetupLayers() 99 | { 100 | Object tagManager = AssetDatabase.LoadMainAssetAtPath("ProjectSettings/TagManager.asset"); 101 | Preset preset = (Preset)AssetDatabase.LoadMainAssetAtPath("Assets/TagManager.preset"); 102 | preset.ApplyTo(tagManager); 103 | } 104 | 105 | private static void OnImportPackageCompleted(string packageName) 106 | { 107 | if (packageName == _PACKAGE_NAME) 108 | { 109 | SetupScenes(); 110 | SetupLayers(); 111 | } 112 | } 113 | } 114 | } -------------------------------------------------------------------------------- /Runtime/Configuration/MiniDiContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using JetBrains.Annotations; 4 | using UnityEngine.Assertions; 5 | 6 | namespace Behc.Configuration 7 | { 8 | public class MiniDiContainer : IDependencyResolver 9 | { 10 | private readonly Dictionary _descriptors; 11 | private readonly IDependencyResolver _parentContext; 12 | 13 | private class InstanceDescriptor 14 | { 15 | public object UnnamedInstance; 16 | public List> NamedInstances; 17 | } 18 | 19 | public MiniDiContainer(IDependencyResolver parentContext = null) 20 | { 21 | _descriptors = new Dictionary(); 22 | _parentContext = parentContext; 23 | } 24 | 25 | public void BindInstance([NotNull] Type type, [NotNull] object instance) 26 | { 27 | Assert.IsNotNull(type); 28 | Assert.IsNotNull(instance); 29 | 30 | if (!_descriptors.TryGetValue(type, out InstanceDescriptor descriptor)) 31 | { 32 | descriptor = new InstanceDescriptor(); 33 | _descriptors.Add(type, descriptor); 34 | } 35 | 36 | Assert.IsNull(descriptor.UnnamedInstance); 37 | descriptor.UnnamedInstance = instance; 38 | } 39 | 40 | public void BindInstance([NotNull] Type type, [NotNull] string name, [NotNull] object instance) 41 | { 42 | Assert.IsNotNull(type); 43 | Assert.IsNotNull(name); 44 | Assert.IsNotNull(instance); 45 | Assert.IsFalse(string.IsNullOrEmpty(name)); 46 | 47 | if (!_descriptors.TryGetValue(type, out InstanceDescriptor descriptor)) 48 | { 49 | descriptor = new InstanceDescriptor(); 50 | _descriptors.Add(type, descriptor); 51 | } 52 | 53 | string normalizedName = Normalize(name); 54 | descriptor.NamedInstances ??= new List>(); 55 | 56 | foreach (var kv in descriptor.NamedInstances) 57 | { 58 | Assert.AreNotEqual(normalizedName, kv.Key); 59 | } 60 | 61 | descriptor.NamedInstances.Add(new KeyValuePair(normalizedName, instance)); 62 | } 63 | 64 | public void BindInstance([NotNull] T instance) 65 | { 66 | BindInstance(typeof(T), instance); 67 | } 68 | 69 | public void BindNamedInstance([NotNull] string name, [NotNull] T instance) 70 | { 71 | BindInstance(typeof(T), name, instance); 72 | } 73 | 74 | public object Resolve(Type type, string name, bool allowUnnamed) 75 | { 76 | if (type == typeof(IDependencyResolver)) 77 | return this; 78 | 79 | InstanceDescriptor descriptor; 80 | if (string.IsNullOrEmpty(name)) 81 | { 82 | if (_descriptors.TryGetValue(type, out descriptor) && descriptor.UnnamedInstance != null) 83 | return descriptor.UnnamedInstance; 84 | 85 | return _parentContext?.Resolve(type, null, true); 86 | } 87 | 88 | string normalizedName = Normalize(name); 89 | 90 | if (_descriptors.TryGetValue(type, out descriptor) && descriptor.NamedInstances != null) 91 | { 92 | foreach (var kv in descriptor.NamedInstances) 93 | { 94 | if (kv.Key == normalizedName) 95 | return kv.Value; 96 | } 97 | } 98 | 99 | object value = _parentContext?.Resolve(type, normalizedName, false); 100 | if (value != null) 101 | return value; 102 | 103 | if (!allowUnnamed) 104 | return null; 105 | 106 | if (descriptor?.UnnamedInstance != null) 107 | return descriptor.UnnamedInstance; 108 | 109 | return _parentContext?.Resolve(type, null, true); 110 | } 111 | 112 | private static string Normalize(string name) => name.ToLowerInvariant().Trim('_'); 113 | } 114 | } -------------------------------------------------------------------------------- /Runtime/Mvp/Models/DataStack.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using UnityEngine.Assertions; 6 | 7 | namespace Behc.Mvp.Models 8 | { 9 | public class DataStack : ReactiveModel, IDataCollection 10 | { 11 | private struct ItemType 12 | { 13 | public object Model; 14 | public Action OnClose; 15 | public object DefaultResultValue; 16 | public bool CanDefaultClose; 17 | } 18 | 19 | private class Collection : IReadOnlyCollection 20 | { 21 | private readonly List _stack; 22 | 23 | public int Count => _stack.Count; 24 | 25 | public Collection(List stack) 26 | { 27 | _stack = stack; 28 | } 29 | 30 | public IEnumerator GetEnumerator() => _stack.Select(i => i.Model).GetEnumerator(); 31 | 32 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 33 | } 34 | 35 | public object TopLevelData => _stack.Count > 0 ? _stack[_stack.Count - 1].Model : null; 36 | public IReadOnlyCollection Data => _collection; 37 | 38 | private readonly List _stack; 39 | private readonly Collection _collection; 40 | 41 | public DataStack() 42 | { 43 | _stack = new List(16); 44 | _collection = new Collection(_stack); 45 | } 46 | 47 | public void Push(object model, Action onClose, TResult defaultResult = default, bool canDefaultClose = true) 48 | { 49 | #if DEBUG 50 | Assert.IsNotNull(model); 51 | foreach (ItemType item in _stack) 52 | Assert.IsFalse(item.Model == model, $"Model {model} already on stack!"); 53 | #endif 54 | void OnClose(object result) => onClose?.Invoke((TResult)result); 55 | _stack.Add(new ItemType { Model = model, OnClose = OnClose, DefaultResultValue = defaultResult, CanDefaultClose = canDefaultClose }); 56 | NotifyChanges(); 57 | } 58 | 59 | public void Remove(object model) 60 | { 61 | int index = _stack.FindIndex(i => i.Model == model); 62 | //TODO: expect last item, should assert that? allow out of order window closing? 63 | Assert.IsTrue(index >= 0, $"Model {model} not found on stack!"); 64 | 65 | ItemType item = _stack[index]; 66 | _stack.RemoveAt(index); 67 | 68 | item.OnClose(item.DefaultResultValue); 69 | 70 | NotifyChanges(); 71 | } 72 | 73 | public void Remove(object model, object result) 74 | { 75 | int index = _stack.FindIndex(i => i.Model == model); 76 | //TODO: expect last item, should assert that? allow out of order window closing? 77 | Assert.IsTrue(index >= 0, $"Model {model} not found on stack!"); 78 | 79 | ItemType item = _stack[index]; 80 | _stack.RemoveAt(index); 81 | 82 | item.OnClose(result); 83 | 84 | NotifyChanges(); 85 | } 86 | 87 | public void RemoveAll() 88 | { 89 | if (_stack.Count == 0) 90 | return; 91 | 92 | ItemType[] copy = _stack.ToArray(); 93 | _stack.Clear(); 94 | 95 | for (int i = copy.Length - 1; i >= 0; i--) 96 | { 97 | copy[i].OnClose(copy[i].DefaultResultValue); 98 | } 99 | 100 | NotifyChanges(); 101 | } 102 | 103 | public bool TryRemoveTopLevel() 104 | { 105 | if (_stack.Count == 0) 106 | return false; 107 | 108 | if (CanDefaultClose()) 109 | { 110 | ItemType item = _stack[_stack.Count - 1]; 111 | _stack.RemoveAt(_stack.Count - 1); 112 | item.OnClose(item.DefaultResultValue); 113 | NotifyChanges(); 114 | } 115 | 116 | return true; 117 | } 118 | 119 | public bool CanDefaultClose() 120 | { 121 | if (_stack.Count == 0) 122 | return false; 123 | 124 | ItemType item = _stack[_stack.Count - 1]; 125 | bool canDefaultClose = (item.Model as ICloseOptions)?.CanDefaultClose ?? true; 126 | return canDefaultClose && item.CanDefaultClose; 127 | } 128 | } 129 | } -------------------------------------------------------------------------------- /Runtime/Configuration/Loaders/BuildSceneConfiguratorLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityEngine.SceneManagement; 4 | 5 | namespace Behc.Configuration.Loaders 6 | { 7 | public class BuildSceneConfiguratorLoader : IConfiguratorLoader 8 | { 9 | public ConfiguratorStatus Status { get; private set; } 10 | 11 | public float Progress => _asyncOperation?.progress ?? 1.0f; 12 | 13 | private readonly string _sceneName; 14 | private readonly bool _removeProxyObjects; 15 | private readonly LocalPhysicsMode _physicsMode; 16 | 17 | private AsyncOperation _asyncOperation; 18 | 19 | public BuildSceneConfiguratorLoader(string sceneName, bool removeProxyObjects = true, LocalPhysicsMode physicsMode = LocalPhysicsMode.None) 20 | { 21 | _sceneName = sceneName; 22 | _removeProxyObjects = removeProxyObjects; 23 | _physicsMode = physicsMode; 24 | Status = ConfiguratorStatus.UNLOADED; 25 | } 26 | 27 | public void Load(IDependencyResolver resolver, Action onComplete) 28 | { 29 | Debug.Assert(Status == ConfiguratorStatus.UNLOADED, $"Invalid status: '{Status}' for '{_sceneName}' scene!"); 30 | 31 | void Finished() 32 | { 33 | _asyncOperation = null; 34 | Status = ConfiguratorStatus.LOADED; 35 | 36 | bool rootElementFound = false; 37 | Scene scene = SceneManager.GetSceneByName(_sceneName); 38 | foreach (GameObject rootObj in scene.GetRootGameObjects()) 39 | { 40 | IConfigurator root = rootObj.GetComponent(); 41 | if (root == null) 42 | continue; 43 | 44 | rootElementFound = true; 45 | try 46 | { 47 | root.Load(resolver); 48 | } 49 | catch (Exception e) 50 | { 51 | Debug.LogException(e); 52 | } 53 | } 54 | 55 | if (!rootElementFound) 56 | Debug.LogError($"Missing scene configurator object for: '{_sceneName}'"); 57 | 58 | //cleanup in 2nd pass - some root object could be reparented during root.Load() 59 | if (_removeProxyObjects) 60 | { 61 | foreach (GameObject rootObj in scene.GetRootGameObjects()) 62 | { 63 | IConfigurator root = rootObj.GetComponent(); 64 | if (root == null) 65 | { 66 | UnityEngine.Object.Destroy(rootObj); 67 | } 68 | } 69 | } 70 | 71 | onComplete?.Invoke(); 72 | } 73 | 74 | // No need to check result.isDone, += will do that and call Finished() sync 75 | Status = ConfiguratorStatus.LOADING; 76 | _asyncOperation = SceneManager.LoadSceneAsync(_sceneName, new LoadSceneParameters { loadSceneMode = LoadSceneMode.Additive, localPhysicsMode = _physicsMode }); 77 | _asyncOperation.completed += op => Finished(); 78 | } 79 | 80 | public void Unload(IDependencyResolver resolver, Action onComplete) 81 | { 82 | Debug.Assert(Status == ConfiguratorStatus.LOADED, $"Invalid status: '{Status}' for '{_sceneName}' scene!"); 83 | 84 | Scene scene = SceneManager.GetSceneByName(_sceneName); 85 | 86 | foreach (GameObject rootObj in scene.GetRootGameObjects()) 87 | { 88 | try 89 | { 90 | IConfigurator root = rootObj.GetComponent(); 91 | root?.Unload(resolver); 92 | } 93 | catch (Exception e) 94 | { 95 | Debug.LogException(e); 96 | } 97 | } 98 | 99 | Status = ConfiguratorStatus.UNLOADING; 100 | _asyncOperation = SceneManager.UnloadSceneAsync(scene, UnloadSceneOptions.UnloadAllEmbeddedSceneObjects); 101 | _asyncOperation.completed += op => 102 | { 103 | Status = ConfiguratorStatus.UNLOADED; 104 | _asyncOperation = null; 105 | onComplete?.Invoke(); 106 | }; 107 | } 108 | } 109 | } --------------------------------------------------------------------------------