Closed ArbitRandomUser closed 2 years ago
@gpucce @Wikunia @Sov-trotter
Merging #231 (40ed0c0) into master (b623c8c) will increase coverage by
0.06%
. The diff coverage is100.00%
.
@@ Coverage Diff @@
## master #231 +/- ##
==========================================
+ Coverage 73.48% 73.54% +0.06%
==========================================
Files 32 32
Lines 6158 6173 +15
==========================================
+ Hits 4525 4540 +15
Misses 1633 1633
Impacted Files | Coverage Δ | |
---|---|---|
src/basics.jl | 92.30% <100.00%> (+0.49%) |
:arrow_up: |
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact)
,ø = not affected
,? = missing data
Powered by Codecov. Last update b623c8c...40ed0c0. Read the comment docs.
Looks cool!
You could usefully add a small description of the mechanism to the docs - perhaps after the Luxor/Cairo - section.
If all the tests still pass, we should be good to go!
@cormullion Added a section in the docs like you asked for . Let me know if it needs more elaboration (and where)
Thanks!
we should be thanking you ... ! :)
The PR
This PR essentially implements a way for Javis to have its own code run when any of these 4 functions i.e
strokepath
,strokepreserve
,fillpath
,fillpreserve
are called. This is needed by Javis to implement some features.https://github.com/ArbitRandomUser/Luxor.jl/tree/javis_branch3
Why ?
Objects in Javis have an
Object.func
which the user defines , typically by making calls toLuxor
functions to draw what the object is. What we require is a way to intercept all calls that paint the current path onto the canvas. Before the canvas is painted we would like to store the current Path and other current drawing information like line width , color alpha etc into Javis' own struct called JPath. ThisJPath
would then allow us to do animations like partially drawing theObject
or morphing it into otherObjects
or other shapes defined by a function.Although morphs have a current implementation , the way to use it is a does not feel natural , one has to define a function that never actually draws anything to the canvas . This along with other constraints on using morphs makes their use in in Javis very awkward.
Take
strokepath
for example . The crux of our problem is changing the behaviour of all calls tostrokepath
wherever they are called, in Javis or through actions passed in Luxor functions (exline(O,O+10,:stroke)
). This cannot be achieved by implementing Javis's ownstrokepath
. Doing so would require users to only callLuxor
functions withaction=:path
and then callingstrokepath
in Javis. If implemented this allows users to use any ofLuxor
s functions freely without these constraints.The first approach we tried was using Cassette.jl. But the approach seemed too hacky . We also did try to "monkey patch" the luxor code in Javis' source but the approach gives warnings about incremental compilation being broken. And in general this would be type piracy.
Essentially we want any valid
Luxor
code that draws something to be usable inside the Object's function.See this topic on discourse
Discourse link
How (it works) ?
The 4 functions in question in the source of
Luxor
have a general structure ofWhat we change it to is
DISPATCHER
is a global variable in luxor. It is a one element array ( hence mutable and can be changed from other modules). In luxor we defineLuxors value for
DISPATCHER
isDefualtLuxor
.The usual method definition instead of dispatching on empty args
funcname()
now dispatch onfuncname(::DefaultLuxor)
And as mentioned before the default argumentless dispatch is changed to
Other modules using Luxor can change this to an instance of their own type (subtyped from LDispatcher) to change the behavior of these functions. And define methods which dispatch on these types to have custom behavior
For example in Javis we do
at render time we set
This way all calls to
strokepath()
eventually end up callingstrokepath(JavisLuxorDispatcher())
defined in JavisJavis PR
In Conclusion
Requesting code to be changed to accomodate the needs of
Javis
is a big favour to ask for... But as of the moment we do not see a cleaner way to implement this and hope you'd give it a consideration. As stated before , this change in no way affects regular usage ofLuxor
withoutJavis
. We have also ensured that this ability to extend Luxor is not Javis specific and any other package that wants to extend these four functions can do so. All theLuxor.jl
tests pass without problems and we have added a test for this dispatch functionality too .