<!DOCTYPE html> <!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]--> <!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]--> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Mixins — Sponge 6.0.0 documentation</title> <link rel="shortcut icon" href="../../_static/favicon.ico"/> <link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" /> <link rel="stylesheet" href="../../_static/spongedocs.css" type="text/css" /> <link rel="index" title="Index" href="../../genindex.html"/> <link rel="search" title="Search" href="../../search.html"/> <link rel="top" title="Sponge 6.0.0 documentation" href="../../index.html"/> <link rel="up" title="Developing Sponge" href="index.html"/> <link rel="next" title="Implementing DataManipulators" href="datamanipulator.html"/> <link rel="prev" title="Debugging Sponge Within the IDE" href="debugging.html"/> <!-- Google Analytics --> <script> (function(S,p,o,n,g,i,e){S['GoogleAnalyticsObject']=g;S[g]=S[g]||function(){ (S[g].q=S[g].q||[]).push(arguments)},S[g].l=1*new Date();i=p.createElement(o), e=p.getElementsByTagName(o)[0];i.async=1;i.src=n;e.parentNode.insertBefore(i,e) })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-59476017-2', 'auto'); ga('send', 'pageview'); </script> <script src="../../_static/js/modernizr.min.js"></script> </head> <body class="wy-body-for-nav" role="document"> <div class="wy-grid-for-nav"> <nav data-toggle="wy-nav-shift" class="wy-nav-side"> <div class="wy-side-scroll"> <div class="wy-side-nav-search"> <div id="sp-logo-container" class="page-scroll"> <a class="logo" href="../../index.html"> <img src="../../_static/spongie-mark-dark.svg"> <span>Sponge</span> <i class="fa fa-fw fa-chevron-down"></i> </a> <div id="sp-logo-menu"> <ul id="sp-logo-dropdown"> <li><a href="https://www.spongepowered.org"><i class="fa-fw fa fa-home"></i>Homepage</a></li> <li><a href="https://forums.spongepowered.org"><i class="fa-fw fa fa-comments"></i>Forums</a></li> <li><a href="https://github.com/SpongePowered"><i class="fa-fw fa fa-code"></i>Code</a></li> <li class="active"><a href="https://docs.spongepowered.org"><i class="fa-fw fa fa-book"></i>Docs</a></li> <li><a href="https://jd.spongepowered.org"><i class="fa-fw fa fa-graduation-cap"></i>Javadocs</a></li> <li><a href="https://forums.spongepowered.org/c/plugins/plugin-releases"><i class="fa-fw fa fa-plug"></i>Plugins</a></li> <li><a href="https://www.spongepowered.org/downloads"><i class="fa-fw fa fa-download"></i>Downloads</a></li> <li><a href="https://www.spongepowered.org/chat"><i class="fa-fw fa fa-comment"></i>Chat</a></li> </ul> </div> </div> <div role="search"> <form id="rtd-search-form" class="wy-form" action="../../search.html" method="get"> <input type="text" name="q" placeholder="Search docs" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> </div> </div> <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation"> <ul> <li class="toctree-l1"><a class="reference internal" href="../../server/index.html">Creating a Server</a></li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="../../preparing/index.html">Preparing for Development</a></li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="../../plugin/index.html">Creating a Plugin</a></li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="../../ore/index.html">Ore Documentation</a></li> </ul> <ul class="current"> <li class="toctree-l1 current"><a class="reference internal" href="../index.html">Contributing to Sponge</a><ul class="current"> <li class="toctree-l2"><a class="reference internal" href="../guidelines.html">Contribution Guidelines</a></li> <li class="toctree-l2"><a class="reference internal" href="../howtogit.html">How to Git(Hub)</a></li> <li class="toctree-l2 current"><a class="reference internal" href="index.html">Developing Sponge</a><ul class="current"> <li class="toctree-l3"><a class="reference internal" href="codestyle.html">Code Style</a></li> <li class="toctree-l3"><a class="reference internal" href="git-implementation.html">Git Workflow for API and Implementations</a></li> <li class="toctree-l3"><a class="reference internal" href="pr.html">Submitting a Pull-Request</a></li> <li class="toctree-l3"><a class="reference internal" href="debugging.html">Debugging Sponge Within the IDE</a></li> <li class="toctree-l3 current"><a class="current reference internal" href="#">Mixins</a></li> <li class="toctree-l3"><a class="reference internal" href="datamanipulator.html">Implementing DataManipulators</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="../spongedocs.html">SpongeDocs Writing</a></li> <li class="toctree-l2"><a class="reference internal" href="../porting.html">Porting Sponge to Other Platforms</a></li> <li class="toctree-l2"><a class="reference internal" href="../versioning.html">Versioning System and Repository Branch Layout</a></li> </ul> </li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="../../about/index.html">About the Sponge Project</a></li> </ul> </div> </div> </nav> <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"> <nav class="wy-nav-top" role="navigation" aria-label="top navigation"> <i data-toggle="wy-nav-top" class="fa fa-bars"></i> <a href="../../index.html">Sponge</a> </nav> <div class="wy-nav-content"> <div class="rst-content"> <div role="navigation" aria-label="breadcrumbs navigation"> <ul class="wy-breadcrumbs"> <li><a href="../../index.html">Docs</a> »</li> <li><a href="../index.html">Contributing to Sponge</a> »</li> <li><a href="index.html">Developing Sponge</a> »</li> <li>Mixins</li> <li class="wy-breadcrumbs-aside"> <a href="https://github.com/SpongePowered/SpongeDocs/blob/fix/https/source/contributing/implementation/mixins.rst" class="fa fa-github"> Edit on GitHub</a> </li> </ul> <hr/> </div> <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> <div itemprop="articleBody"> <div class="section" id="mixins"> <h1>Mixins<a class="headerlink" href="#mixins" title="Permalink to this headline">¶</a></h1> <div class="admonition note"> <p class="first admonition-title">Note</p> <p class="last">This page applies to SpongeCommon, SpongeForge, and SpongeVanilla as these three repositories utilize Mixins to hook into the underlying implementations (Vanilla Minecraft server and Forge).</p> </div> <p>Mixins are a way of modifying java code at runtime by adding additional behavior to classes. They enable transplanting of intended behavior into existing Minecraft objects. Mixins are necessary for all official Sponge implementations to function.</p> <p>A basic introduction to some of the core concepts underpinning the mixin functionality we’re using to implement Sponge is available at the <a class="reference external" href="https://github.com/SpongePowered/Mixin/wiki/">Mixin Wiki</a></p> <p><em>It starts with absolute basics. If you’re an experienced java developer, feel free to skip to section 4, where the mixins themselves are actually discussed.</em></p> <p>If you’re looking to get started writing mixins, we also strongly recommend carefully examining all of the examples in the <a class="reference external" href="https://github.com/SpongePowered/SpongeCommon/tree/stable-6/src/example/java/org/spongepowered">SpongeCommon repository</a> which are extensively documented and cover many of the more complex scenarios. You should also consult the Javadoc of the Mixin repository itself, since almost everything is already documented.</p> <p><strong>Caveat: When contributing mixins, note that you can use neither anonymous classes nor lambda expressions.</strong></p> <p>This means expressions like the following will cause mixins to fail horribly and bring death and destruction upon all that attempt to use Sponge.</p> <div class="highlight-java"><div class="highlight"><pre><span></span><span class="k">return</span> <span class="k">new</span> <span class="n">Predicate</span><span class="o"><</span><span class="n">ItemStack</span><span class="o">>()</span> <span class="o">{</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">test</span><span class="o">(</span><span class="n">ItemStack</span> <span class="n">input</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="n">input</span><span class="o">.</span><span class="na">getItem</span><span class="o">().</span><span class="na">equals</span><span class="o">(</span><span class="n">Items</span><span class="o">.</span><span class="na">golden_apple</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> </pre></div> </div> <div class="highlight-java"><div class="highlight"><pre><span></span><span class="k">return</span> <span class="n">input</span> <span class="o">-></span> <span class="n">input</span><span class="o">.</span><span class="na">getItem</span><span class="o">().</span><span class="na">equals</span><span class="o">(</span><span class="n">Items</span><span class="o">.</span><span class="na">golden_apple</span><span class="o">);</span> </pre></div> </div> <div class="highlight-java"><div class="highlight"><pre><span></span><span class="k">return</span> <span class="k">this</span><span class="o">::</span><span class="n">checkItem</span><span class="o">;</span> </pre></div> </div> <p>This applies to all classes that are annotated with <code class="docutils literal"><span class="pre">@Mixin</span></code>. Classes that are not touched by the mixin processor may make use of those features. However, you can use a static utility class to create your anonymous classes, as unlike your mixin class that utility class will still exist at runtime, while your mixin class will be merged into the specified target class. The following code therefore will work.</p> <div class="highlight-java"><div class="highlight"><pre><span></span><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ItemUtil</span> <span class="o">{</span> <span class="kd">public</span> <span class="kd">static</span> <span class="n">Predicate</span><span class="o"><</span><span class="n">ItemStack</span><span class="o">></span> <span class="nf">typeChecker</span><span class="o">(</span><span class="kd">final</span> <span class="n">Item</span> <span class="n">item</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="k">new</span> <span class="n">Predicate</span><span class="o"><</span><span class="n">ItemStack</span><span class="o">>()</span> <span class="o">{</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">test</span><span class="o">(</span><span class="n">ItemStack</span> <span class="n">input</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="n">input</span><span class="o">.</span><span class="na">getItem</span><span class="o">().</span><span class="na">equals</span><span class="o">(</span><span class="n">item</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> <span class="o">}</span> <span class="o">}</span> <span class="nd">@Mixin</span><span class="o">(</span><span class="n">TargetClass</span><span class="o">.</span><span class="na">class</span><span class="o">)</span> <span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">SomeMixin</span> <span class="o">{</span> <span class="kd">public</span> <span class="n">Predicate</span><span class="o"><</span><span class="n">ItemStack</span><span class="o">></span> <span class="nf">someFunction</span><span class="o">()</span> <span class="o">{</span> <span class="k">return</span> <span class="n">ItemUtil</span><span class="o">.</span><span class="na">typeChecker</span><span class="o">(</span><span class="n">Items</span><span class="o">.</span><span class="na">golden_apple</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> </pre></div> </div> <div class="admonition note"> <p class="first admonition-title">Note</p> <p class="last">The Mixin project will be servicing a number of other projects in addition to Sponge itself. Therefore Mixin has its’ own documentation together with the repository.</p> </div> </div> </div> </div> <footer> <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation"> <a href="datamanipulator.html" class="btn btn-neutral float-right" title="Implementing DataManipulators" accesskey="n" rel="next">Next <span class="fa fa-angle-right"></span></a> <a href="debugging.html" class="btn btn-neutral" title="Debugging Sponge Within the IDE" accesskey="p" rel="prev"><span class="fa fa-angle-left"></span> Previous</a> </div> <hr/> <section id="license"> <p>Except where otherwise noted, <a xmlns:dct="http://purl.org/dc/terms/" xmlns:cc="http://creativecommons.org/ns#" property="dct:title" rel="cc:attributionURL" href="https://github.com/SpongePowered/SpongeDocs">SpongeDocs</a> is licensed under a <a rel="license" href="https://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>. </p> <a id="license-icons" rel="license" href="https://creativecommons.org/licenses/by-sa/4.0/" title="CC-BY-SA" aria-hidden="true">cba</a> </section> </footer> </div> </div> </section> </div> <div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions"> <span class="rst-current-version" data-toggle="rst-current-version"> <i class="fa fa-book"> <span>SpongeDocs</span></i> v: 6.0.0 <span class="fa fa-caret-down"></span> </span> <div id="versions" class="rst-other-versions"> <dl> <dt>Contribute</dt> <dd><a href="https://github.com/SpongePowered/SpongeDocs/blob/fix/https/source/contributing/implementation/mixins.rst">Source</a></dd> <dd><a href="https://github.com/SpongePowered/SpongeDocs/edit/fix/https/source/contributing/implementation/mixins.rst">Edit</a></dd> </dl> </div> </div> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT:'../../', VERSION:'6.0.0', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../../_static/jquery.js"></script> <script type="text/javascript" src="../../_static/underscore.js"></script> <script type="text/javascript" src="../../_static/doctools.js"></script> <script type="text/javascript" src="../../_static/spongedocs.js"></script> <script type="text/javascript" src="../../_static/js/theme.js"></script> <script type="text/javascript"> jQuery(function () { SphinxRtdTheme.StickyNav.enable(); }); </script> </body> </html>