Butterfly - Small and powerful weapons, own it, let your Android are developed like Tiger, Carry whole game!

Overview

Butterfly

Butterfly - Small and powerful weapons, own it, let your Android are developed like Tiger, Carry whole game!

Only the mightiest and most experienced of warriors can wield the Butterfly, but it provides incredible dexterity in combat.

Item introduction: +30 Agility +35% Evasion +25 Attack Damage +30 Attack Speed

Read this in other languages: 中文, English, Change Log

Usage

import

repositories {
  maven { url 'https://jitpack.io' }
}
apply plugin: 'kotlin-kapt'

dependencies {
  implementation 'com.github.ssseasonnn.Butterfly:butterfly:1.0.0'
  kapt 'com.github.ssseasonnn.Butterfly:compiler:1.0.0'
}

Butterfly achieve different functions through two different annotations:

  • Agile Used for page navigation
  • Evade Used for component communication

Agile

  • Page navigation

By adding an Agile annotation to Activity, set the corresponding scheme, then you can navigate through butterfly, or navigate and get the return data.

@Agile("test/scheme")
class AgileTestActivity : AppCompatActivity() {
    //...
}

//navigation
Butterfly.agile("test/scheme").carry()

//Navigate and get the return data
Butterfly.agile("test/scheme")
    .carry {
        val result = it.getStringExtra("result")
        binding.tvResult.text = result
    }
  • Pass parameter

Agile supports a parameter navigation, there are two ways, one is to add parameters to scheme to the Scheme by calling the parameter method, or the mixing of the two, then the page after navigationGet the corresponding parameters

//add parameters to scheme
Butterfly.agile("test/scheme?a=1&b=2").carry()

//call params method
Butterfly.agile("test/scheme?a=1&b=2")
    .params("intValue" to 1)
    .params("booleanValue" to true)
    .params("stringValue" to "test value")
    .carry()
  • Parse parameters

On the navigation purpose page, you can get the passed parameter value by using the key field of the parameter

@Agile("test/scheme")
class AgileTestActivity : AppCompatActivity() {
	val a by lazy { intent?.getStringExtra("a") ?: "" }
	val b by lazy { intent?.getStringExtra("b") ?: "" }
    val intValue by lazy { intent?.getIntExtra("intValue", 0) ?: 0 }
}

In addition to manual parameter parsing, Bracer can also be equipped for fully automated parameter parsing

() val b by params() val intValue by params() }">
@Agile("test/scheme")
class AgileTestActivity : AppCompatActivity() {
	val a by params<String>()
	val b by params<String>()
	val intValue by params<Int>()
}

See Details on how Bracer is used: Github Bracer

  • Interceptors

Agile supports interceptors that can be used to preprocess parts of logic, such as login detection, before navigation Navigation is also possible in the interceptor, but to avoid the interceptor nesting doll, the skipInterceptor() method needs to be added to ignore the interceptor

//Implement a custom interceptor
class TestInterceptor : ButterflyInterceptor {
    override fun shouldIntercept(agileRequest: AgileRequest): Boolean {
        //Detects whether interception is required
        return true
    }

    override suspend fun intercept(agileRequest: AgileRequest) {
        //Handles the interception logic
        println("intercepting")
        delay(5000)
        println("intercept finish")
    }
}

//Register the interceptor
ButterflyCore.addInterceptor(TestInterceptor())

//Skip the interceptor
Butterfly.agile("test/scheme").skipInterceptor().carry()
  • Action

In addition to supporting page navigation, Agile also supports navigation Action, action has no pages, and can do some logic processing First let the custom Class inherit the Action, then add @Agile annotations and set the scheme, and the rest is consistent with the page navigation

@Agile("test/action")
class TestAction : Action {
    override fun doAction(context: Context, scheme: String, data: Bundle) {
        //The parameters passed in can be obtained from the data
        Toast.makeText(context, "This is an Action", Toast.LENGTH_SHORT).show()
    }
}

//Start Action
Butterfly.agile("test/action").carry()

//Action also supports pass parameters
Butterfly.agile("test/action?a=1&b=2").carry()

//params
Butterfly.agile("test/action")
    .params("intValue" to 1)
    .carry()
  • Process control

In addition to directly calling carry navigation, Agile can also call flow to return the Flow object, which can be used to process the navigation flow

Butterfly.agile("test/scheme").flow()
		.onStart { println("start") }
		.onCompletion { println("complete") }
		.onEach { println("process result") }
		.launchIn(lifecycleScope)

Evade

Butterfly can communicate between any component using a simple two annotations without any direct or indirect dependency between the components

For example, there are two components: Module Foo and Module Bar that require communication

In Module Foo, define the interface and add the Evade annotation:

@Evade
interface Home {
	//Define the method
    fun showHome(fragmentManager: FragmentManager, container: Int)
}

In module Bar, define the implementation, and add the EvadeImpl annotation:

//The implementation class name must end in Impl
@EvadeImpl
class HomeImpl {
    val TAG = "home_tag"

	//To implement a method in the Home interface, the method name and method parameters must be the same
    fun showHome(fragmentManager: FragmentManager, container: Int) {
        val homeFragment = HomeFragment()
        fragmentManager.beginTransaction()
            .replace(container, homeFragment, TAG)
            .commit()
    }
}

Since Evade uses the class name as an important basis for defining and implementing associations, the interface class name and the implementation class name must be the same, and the implementation class name ends in Impl. If you cannot use a class name as an association, you can also use the same string type as the association key

@Evade(identity = "same key")
interface Home

@EvadeImpl(identity = "same key")
class OtherNameImpl

Then in Module Foo, you can use the evaluate method to get home and call:

val home = Butterfly.evade<Home>()
home.showHome(supportFragmentManager, R.id.container)

In addition, Evade also supports strong association type communication in the form of sinking dependencies

For example, the following three components: the common component Module Base, Module Foo, and Module Bar

First sink the Home interface into the common component Module Base:

@Evade
interface Home {
    fun showHome(fragmentManager: FragmentManager, container: Int)
}

Then in the Module Bar, implement the interface:

//The same naming convention needs to be used, and the implementation class name must end in Impl
@EvadeImpl
class HomeImpl : Home {
    val TAG = "home_tag"

    override fun showHome(fragmentManager: FragmentManager, container: Int) {
        val homeFragment = HomeFragment()
        fragmentManager.beginTransaction()
            .replace(container, homeFragment, TAG)
            .commit()
    }
}

Then in Module Foo, you can use the evaluate method to get home and call:

val home = Butterfly.evade<Home>()
home.showHome(supportFragmentManager, R.id.container)

Routing table

Butterfly generates a route table for each Module that uses the annotation, and the naming convention is: Butterfly[module name]Module

Manual registration:

class DemoApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        //register
        ButterflyCore.addModule(ButterflyHomeModule())
        ButterflyCore.addModule(ButterflyFooModule())
        ButterflyCore.addModule(ButterflyBarModule())
    }
}

To register automatically with a plugin:

  1. Add plugin dependencies
//using plugins DSL:
plugins {
    id "io.github.ssseasonnn.butterfly" version "1.0.1"
}

//or useing legacy plugin application:
buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath "io.github.ssseasonnn:plugin:1.0.1"
    }
}

//add plugin
apply plugin: "io.github.ssseasonnn.butterfly"
  1. Implement your own Application class
class DemoApplication : Application() {
    override fun onCreate() {
        super.onCreate()
    }
}

Proguard config

-keep public class zlc.season.butterfly.module.**
-keep public class zlc.season.butterfly.annotation.**
-keep public class zlc.season.butterfly.ButterflyCore {*;}
-keep public class * extends zlc.season.butterfly.Action

-keep @zlc.season.butterfly.annotation.Agile class * {*;}
-keep @zlc.season.butterfly.annotation.Evade class * {*;}
-keep @zlc.season.butterfly.annotation.EvadeImpl class * {*;}

License

Copyright 2022 Season.Zlc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
You might also like...
Stop crashes from closing your game

CrashPatch Discord server (CLICK HERE TO GET SUPPORT) CrashPatch is a Minecraft

A small project demonstrates how to manipulate to TenIO framework.
A small project demonstrates how to manipulate to TenIO framework.

TenIO Common Module TenIO is an open-source project to create multiplayer online games that includes a java NIO (Non-blocking I/O) based server specif

Multiplayer Dots and Boxes game for Android

Multiplayer Dots and Boxes game for Android. One player is the server, and the rest connect to them. Has player customization and in-game chat! Still in development, but fully compatible with version 2.0 of my NetDot protocol.

simple game implements with kotlin and jetpack.(covered by unit test)
simple game implements with kotlin and jetpack.(covered by unit test)

Simple Spy Game: Source Code 🚨 Published version 🚨 This repository contains a detailed game app that implements simple game using Koin, Room, Corout

Spooky house game with monsters and sounds
Spooky house game with monsters and sounds

SHGWMAS Spooky house game with monsters and sounds INSTRUCTIONS to play the game you must: have a brain downloaded the world + jar from the releases t

Terminal Game. Black and White have only pawns. White wins if their pawn moved to 8th line. Black wins if their pawn moves to 1st line. If black or white haven't any move, then no one wins(stalemate))

Only-Pawns-Chess Terminal game for 2 players Regular chess but all sides have only pawns Rules This game extend all the rules of regular chess but it

Tic Tac Toe is a two-player game in which the objective is to take turns and mark the correct spaces in a 3x3 (or larger) grid
Tic Tac Toe is a two-player game in which the objective is to take turns and mark the correct spaces in a 3x3 (or larger) grid

Tic Tac Toe is a two-player game in which the objective is to take turns and mark the correct spaces in a 3x3 (or larger) grid.

 A Ktor-based server that handles game process, user registration and packs provision
A Ktor-based server that handles game process, user registration and packs provision

Polyhoot! Server backend A Ktor-based server that handles game process, user registration and packs provision Deploying server locally You can deploy

An easy open source Android Native Game FrameWork.
An easy open source Android Native Game FrameWork.

JustWeEngine - Android Game FrameWork An easy open source Android Native Game FrameWork. Engine Flow Chart How To Use? Import Engine's module as Libra

Owner
Season
会写点代码
Season
Our maze game is an 2d-animation game developed using android studio.

Our maze game is an 2d-animation game developed using android studio. The game consists of a ball and a board with a hole in the center of it. We are using accelerometer as controller to guide ball towards the hole. T

Suraj Devgan 6 Nov 29, 2022
This is an application that is about an X / O game. You can enter the names of the game, and there is also a screen for those who win and there is a button to continue playing and the game determines the result of each player

Game-X-O This is an application that is about an X / O game. You can enter the names of the game, and there is also a screen for those who win and the

Mohamed Rafat 2 Aug 20, 2022
Chrome's Dino T-Rex game developed in Jetpack Compose

Chrome's Dino T-Rex game developed in Jetpack Compose

Wajahat Karim 230 Dec 29, 2022
A simple game that was developed using Kotlin

TruthOrDare About the App: A simple Android game that reminds you of your childhood . How to use? 1 - Clone or download the Project to your machine. 2

Leandro Santos 1 Jan 15, 2022
A small game using Fleks Entity Component System.

Dinoleon TBD Credits Arks: Dino Sprites Szadi art: Platformer Fantasy Free Package craftpix.net: Jungle Cartoon GUI Soup of Justice Font cooltext.com

Simon 4 Oct 3, 2022
WordleSolver - A small attempt to solve the Wordle game (in Spanish) without thinking too much

Wordle solver A small attempt to solve the Wordle game (in Spanish) without thin

Eduardo Pascua 2 Sep 30, 2022
Tangler a small casual puzzle inspired by the Tantrix board game but with a different twist.

Tangler game. Written in Kotlin, for desktop (Java JAR) and Android. The iOS module is present but was not built or tested.

Andrzej Novosiolov 6 Jan 6, 2023
Game made with Korge (Kotlin Multiplatform game engine)

MolesAttack Kotlin Multiplatform Game Play Html/js: https://feliperce.github.io/MolesAttack-Distribution/ Jar: https://feliperce.github.io/MolesAttack

Felipe Rodrigues 10 May 30, 2022
🎮 A Minesweeper like puzzle game, built using Jetpack Compose, for Android.

Minesweeper w/ Jetpack Compose This is a Minesweeper-like puzzle game, built using Jetpack Compose, for Android. The objective of this game is to clea

Jaya Surya Thotapalli 64 Jan 2, 2023
This game teases your memory power....

MemoryGame This is a game which streches your memory capacity. This game has 2 activities startActivity & mainActivity. The startActivity helps you to

null 1 Dec 9, 2021