Giter VIP home page Giter VIP logo

statearts's Introduction

StateArts

Intellij / Android Studio plugin that creates state machine diagram from state machine. The Art of states

How to install?

Make sure you have graphviz installed

This plugin works based on a opensource command line tool called Graphviz. Make sure Graphviz in installed on your path
  • Install graphviz on mac using brew
    brew install graphviz

  • Install graphviz on ubuntu/linux based system
    sudo apt-get install graphviz

  • Install graphviz on windows Use the windows graphviz installer

  • Android Studio

Goto File > Preferences/Settings > plugins >Browse Repositorie > Search for "State Art" > Install and Restart

  • Intellij

Goto File > Preferences/Settings > plugins >Market Place > Search for "State Art" > Install and Restart

State machine line marker

Create state diagram in a click

State and Arts

How it works?

Here is a detailed Medium Post

FAQ:

  1. How can I help?
  • Keep the โญ shining and spirit high: Add your review and ratings at Intellij plugin repository
  • Submit PR
  • Create feature requests/ report issues
  1. How to make sure graphviz is properly installed?
    Run dot -V from your termninal you should see some output which looks similar to this
    dot - graphviz version 2.40.1 (20161225.0304)

statearts's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

statearts's Issues

dontTransition(SideEffect) doesn't render to well

If I have this setup:

state<State.Idle> {
    on<Event.OnAuthenticate> { transitionTo(..., ...) }
    on<Event.OnShowSomething> { dontTransition(SideEffect.ShowSomething) }
}
state<State.Authenticating> {  ...  }

It will throw an error saying:

StateMachineParserException(message=Malformed StateMachine:Event/state Authenticating can't appear after the Event(event=OnSomething):)

If I switch states:

state<State.Authenticating> {  ...  }
state<State.Idle> {
    on<Event.OnAuthenticate> { transitionTo(..., ...) }
    on<Event.OnShowSomething> { dontTransition(SideEffect.ShowSomething) }
}

It generates the .dot file but:

 Idle -> Authenticating [label="OnAuthenticate"]
 Idle -> Idle [label="OnAuthenticate"]

instead of:

 Idle -> Authenticating [label="OnAuthenticate"]
 Idle -> Idle [label="OnShowSomething"]

Currently I can't use fun S.dontTransition(sideEffect: SIDE_EFFECT? = null) if I want to use your plugin:

state<State.Idle> {
    ...
    on<Event.OnShowSomething> {
        //dontTransition(SideEffect.ShowSomething)
        transitionTo(State.Idle, SideEffect.ShowSomething)
    }
}

graphviz:

dot - graphviz version 2.49.0 (20210828.1703)

Android Studio:

Android Studio Arctic Fox | 2020.3.1 Patch 2
Build #AI-203.7717.56.2031.7678000, built on August 26, 2021
Runtime version: 11.0.10+0-b96-7281165 x86_64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 11.4
GC: G1 Young Generation, G1 Old Generation
Memory: 4096M
Cores: 4
Registry: ide.windowSystem.autoShowProcessPopup=true, external.system.auto.import.disabled=true, debugger.watches.in.variables=false, ide.images.show.chessboard=true
Non-Bundled Plugins: com.intellij.marketplace, mobi.hsz.idea.gitignore, com.thoughtworks.gauge, org.jetbrains.kotlin, com.google.mad-scorecard, com.jetbrains.kmm, com.squareup.sqldelight, dev.vinayshetty.stateart

Improve Lexer Regexes

Thanks for your amazing plugin. To further improve the usage of your plugin, please think about the following suggestions:

  • The regex that is used for recognizing State Machine states scans for every sign in front of the word state link. This will lead to a defunct plugin as soon as there're variable/method names like "setNavigationState()". Maybe there is a solution to filter out the word state at the end or in the middle of method/variable names, maybe a a \s in front of the world state would already suffice.

  • Larger state machines diagrams can get really confusing with the used default parameters. I'd suggest some configuration settings like: orientation, fileType, vertical/horizontal spacing... Currently we have to copy the generated .dot file and edit it manually to add parameters like nodesep=0.3; ranksep=1; concentrate=true; rankdir=LR.

Keep up the good work and thanks in advance

generate plantuml instead of image file

the current image file is not very well laid out if the graph is complex. If the tool can generate a plantuml state diagram, the final diagram would be much more useful. For example I could go into the plantUml diagram and fix the formatting to make it pretty.

Not seeing the line marker

I'm not sure which additional data I can provide that can help with this issue (except for providing the FSM itself which I can't...)

Versions:
IntelliJ 2019.2.2
Kotlin 1.3.5
State Art 0.5
Tinder state machine 0.1.2

"Too complex, sorry." message when trying to render MatterStateMachine

Clicking on in the S gutter icon generates the error message

Cannot perform operation, Too complex, sorry.

State machine is the one defined in StateMachineTest: https://github.com/Tinder/StateMachine/blob/0f7964206bd8dbc70f5a30fed0b1db76bfcc1b24/src/test/kotlin/com/tinder/StateMachineTest.kt#L18

IntelliJ:

IntelliJ IDEA 2021.3 (Community Edition)
Build #IC-213.5744.223, built on November 27, 2021
Runtime version: 11.0.13+7-b1751.19 aarch64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 12.1
GC: G1 Young Generation, G1 Old Generation
Memory: 2048M
Cores: 10
Non-Bundled Plugins:
    dev.vinayshetty.stateart (0.5)

Kotlin: 213-1.6.10-release-923-IJ5744.223

Associated stack trace

java.lang.Throwable: '#LineMarkerInfo(T, TextRange, Icon, int, Function, GutterIconNavigationHandler, Alignment)' is deprecated and going to be removed soon. Please use `LineMarkerInfo(T, TextRange, Icon, Function, GutterIconNavigationHandler, Alignment, Supplier)` instead
	at com.intellij.openapi.diagnostic.Logger.error(Logger.java:182)
	at com.intellij.diagnostic.PluginException.reportDeprecatedUsage(PluginException.java:105)
	at com.intellij.codeInsight.daemon.LineMarkerInfo.<init>(LineMarkerInfo.java:162)
	at dev.vinayshetty.stateart.intellij.StateArtLineMarker.getLineMarkerInfo(StateArtLineMarker.kt:30)
	at com.intellij.codeInsight.daemon.impl.LineMarkersPass.queryProviders(LineMarkersPass.java:160)
	at com.intellij.codeInsight.daemon.impl.LineMarkersPass.lambda$doCollectInformation$3(LineMarkersPass.java:85)
	at com.intellij.codeInsight.daemon.impl.Divider.divideInsideAndOutsideInOneRoot(Divider.java:115)
	at com.intellij.codeInsight.daemon.impl.LineMarkersPass.doCollectInformation(LineMarkersPass.java:80)
	at com.intellij.codeHighlighting.TextEditorHighlightingPass.collectInformation(TextEditorHighlightingPass.java:56)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$doRun$1(PassExecutorService.java:414)
	at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1084)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$doRun$2(PassExecutorService.java:407)
	at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$executeProcessUnderProgress$12(CoreProgressManager.java:624)
	at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:698)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computeUnderProgress(CoreProgressManager.java:646)
	at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:623)
	at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:66)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.doRun(PassExecutorService.java:406)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$run$0(PassExecutorService.java:382)
	at com.intellij.openapi.application.impl.ReadMostlyRWLock.executeByImpatientReader(ReadMostlyRWLock.java:174)
	at com.intellij.openapi.application.impl.ApplicationImpl.executeByImpatientReader(ApplicationImpl.java:181)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.run(PassExecutorService.java:380)
	at com.intellij.concurrency.JobLauncherImpl$VoidForkJoinTask$1.exec(JobLauncherImpl.java:184)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)

Plugin does not ignore commented code.

Minimal example:

sealed class State {
    object Closed : State()
    object Open : State()
}

sealed class Event {
    object OnOpen : Event()
    object OnClose : Event()
}

val stateMachine = StateMachine.create<State, Event, SideEffect> {
    initialState(State.Open)
    state<State.Open> {
        on<Event.OnClose> {
            transitionTo(State.Closed)
        }
    }
//    state<State.Broken> {
//        on<Event.Impossible> {
//            transitionTo(State.Weird, SideEffect.LogWeird)
//        }
//    }
}

The resulting graph contains commented (and infeasible) state:
stateMachine

.dot is created but no .png

Running on M1 Pro the plugin generates the .dot file but not the .png
Running on Intel it works, could be just a coincidence. Any thoughts?

Cannot perform operation. Too complex.

Hello, I'm using Android Studio on Linux and this problem happened to me, and the error statement is:

Cannot perform operation. Too complex, sorry.

The Stacktrace is

StateMachineParserException(message=An eventName should't appear right after previous event,add transition for event OnLoadData
                                hint:OnLoadData appears after Event(event=OnNavigationOut)
                            )
	at dev.vinayshetty.stateart.parser.StateMachineParser.handleParserEvent(StateMachineParser.kt:56)
	at dev.vinayshetty.stateart.parser.StateMachineParser.event(StateMachineParser.kt:15)
	at dev.vinayshetty.stateart.lexer.StateMachineLexerImpl.lexLine(StateMachineLexerImpl.kt:39)
	at dev.vinayshetty.stateart.lexer.StateMachineLexerImpl.lex(StateMachineLexerImpl.kt:14)
	at dev.vinayshetty.stateart.intellij.StateArtLineMarker.writeDotFile(StateArtLineMarker.kt:54)
	at dev.vinayshetty.stateart.intellij.StateArtLineMarker.access$writeDotFile(StateArtLineMarker.kt:26)
	at dev.vinayshetty.stateart.intellij.StateArtLineMarker$getLineMarkerInfo$2.navigate(StateArtLineMarker.kt:37)
	at com.intellij.codeInsight.daemon.NavigateAction.actionPerformed(NavigateAction.java:62)
	at com.intellij.openapi.actionSystem.ex.ActionUtil.performActionDumbAware(ActionUtil.java:281)
	at com.intellij.openapi.actionSystem.ex.ActionUtil.performActionDumbAwareWithCallbacks(ActionUtil.java:275)
	at com.intellij.openapi.editor.impl.EditorGutterComponentImpl.performAction(EditorGutterComponentImpl.java:1945)
	at com.intellij.openapi.editor.impl.EditorGutterComponentImpl.mouseReleased(EditorGutterComponentImpl.java:1904)
	at com.intellij.openapi.editor.impl.EditorImpl.processMouseReleased(EditorImpl.java:2344)
	at com.intellij.openapi.editor.impl.EditorImpl$MyMouseAdapter.lambda$runMouseReleasedCommand$1(EditorImpl.java:3886)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:220)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:177)
	at com.intellij.openapi.editor.impl.EditorImpl$MyMouseAdapter.runMouseReleasedCommand(EditorImpl.java:3888)
	at com.intellij.openapi.editor.impl.EditorImpl$MyMouseAdapter.mouseReleased(EditorImpl.java:3778)
	at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:298)
	at java.desktop/java.awt.Component.processMouseEvent(Component.java:6652)
	at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3345)
	at java.desktop/java.awt.Component.processEvent(Component.java:6417)
	at java.desktop/java.awt.Container.processEvent(Container.java:2263)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5027)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4859)
	at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
	at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
	at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
	at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2784)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4859)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:778)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:751)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:749)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:748)
	at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:976)
	at com.intellij.ide.IdeEventQueue.dispatchMouseEvent(IdeEventQueue.java:911)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:840)
	at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$8(IdeEventQueue.java:454)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:773)
	at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$9(IdeEventQueue.java:453)
	at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:828)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:507)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Hardcoded Graphviz path for Windows

Currently path for graphviz executable is hardcoded for specific version, making it hard to use for Windows users (hardcoded version is already outdated). How about using graphviz by using system PATH? Only downside is forcing users to add graphviz executable path to system PATH. Anyway, great work.

Graphviz path is hardcoded for Windows. Throws error if Graphviz != 2.38

The path for Graphviz is hardcoded for Windows. From StateArtLineMarker.kt:

    private fun getExePath(): String {
        val os = System.getProperty("os.name").toLowerCase()
        return if (os.contains("win")) {
            "c:/Program Files (x86)/Graphviz 2.38/bin/dot.exe" //Only works in windows if Graphviz version is 32 bit 2.38
        } else if (os.contains("mac")) {
            "/usr/local/bin/dot"
        } else {
            //consider Linux based
            "/usr/bin/dot"
        }
    }

The plugin fails with the incorrect error "Cannot perform operation. Too complex sorry".

As a workaround, you can make a symlink to the current version of your library

mklink /J "C:\Program Files (x86)\Graphviz 2.38" "C:\Program Files\Graphviz"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.