├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── appveyor.yml
├── assets
└── unihx-logo.png
├── build-tool
├── build.hxml
├── res
│ └── Template.hxproj
└── src
│ └── Cli.hx
├── extraParams.hxml
├── haxe
├── Log.hx
└── Timer.hx
├── lib
├── Unity.CecilTools.dll
├── Unity.DataContract.dll
├── Unity.IvyParser.dll
├── Unity.Locator.dll
├── Unity.SerializationLogic.dll
├── UnityEditor.Graphs.dll
├── UnityEditor.dll
└── UnityEngine.dll
├── run.n
├── tests
├── build-unity.hxml
├── build.hxml
├── project
│ ├── .gitignore
│ ├── Assets
│ │ ├── TestEntryPoint.cs
│ │ ├── TestEntryPoint.cs.meta
│ │ ├── TestScene.unity
│ │ ├── TestScene.unity.meta
│ │ ├── bin-Debug.dll
│ │ └── bin-Debug.dll.meta
│ └── ProjectSettings
│ │ ├── AudioManager.asset
│ │ ├── DynamicsManager.asset
│ │ ├── EditorBuildSettings.asset
│ │ ├── EditorSettings.asset
│ │ ├── GraphicsSettings.asset
│ │ ├── InputManager.asset
│ │ ├── NavMeshLayers.asset
│ │ ├── NetworkManager.asset
│ │ ├── Physics2DSettings.asset
│ │ ├── ProjectSettings.asset
│ │ ├── QualitySettings.asset
│ │ ├── TagManager.asset
│ │ └── TimeManager.asset
└── src
│ ├── CmdTests.hx
│ ├── UnityTests.hx
│ └── tests
│ └── YieldTests.hx
├── unihx
├── _internal
│ ├── Compiler.hx
│ ├── PrivateAccessMacro.hx
│ ├── PrivateTypeAccess.hx
│ ├── StructHelper.hx
│ ├── Yield.hx
│ ├── YieldBase.hx
│ ├── YieldGenerator.hx
│ └── editor
│ │ ├── AllowDragDrop.hx
│ │ ├── AssetProcessor.hx
│ │ ├── HaxeCompiler.hx
│ │ └── HaxeProperties.hx
└── inspector
│ ├── AnimationCurve.hx
│ ├── Button.hx
│ ├── Color.hx
│ ├── ConstLabel.hx
│ ├── Fold.hx
│ ├── InspectorBuild.hx
│ ├── IntField.hx
│ ├── Label.hx
│ ├── Layer.hx
│ ├── Macro.hx
│ ├── ObjectField.hx
│ ├── Password.hx
│ ├── Range.hx
│ ├── Rect.hx
│ ├── Select.hx
│ ├── Slider.hx
│ ├── Space.hx
│ ├── Tag.hx
│ ├── TextArea.hx
│ ├── Vector2.hx
│ ├── Vector3.hx
│ └── Vector4.hx
└── unityengine
├── Bounds.hx
├── BoundsData.hx
├── Color.hx
├── Color32.hx
├── Color32Data.hx
├── ColorData.hx
├── HaxeBehaviour.hx
├── Matrix4x4.hx
├── Matrix4x4Data.hx
├── Quaternion.hx
├── QuaternionData.hx
├── Rect.hx
├── RectData.hx
├── Vector2.hx
├── Vector2Data.hx
├── Vector3.hx
├── Vector3Data.hx
├── Vector4.hx
└── Vector4Data.hx
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | *.swo
3 | bin
4 |
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # example travis.yml haxe configuration
2 | language: objective-c # change this to c to test on a linux machine
3 | env:
4 | global:
5 | - OS=mac # add this too to let the script know that the OS is a mac
6 | # - ARCH=i686 # add this to run in 32-bit mode. See availability at README
7 | matrix:
8 | - TARGET=cs
9 |
10 | matrix:
11 | fast_finish: true
12 |
13 | before_install: # clone travis-hx repo
14 | - travis_retry git clone --depth=50 --branch=master git://github.com/waneck/travis-hx.git ~/travis-hx
15 |
16 | install: # setup the target
17 | - ~/travis-hx/setup.sh
18 | - haxelib install utest
19 | - haxelib dev unihx "$TRAVIS_BUILD_DIR"
20 | - cd ~
21 | - curl -L "https://docs.google.com/uc?export=download&id=0B8FjDKR0nfqoQmpOYW44S2c3SU0" -o mac.tar.gz
22 | - tar -zxf mac.tar.gz
23 | - chmod +x test.app/Contents/MacOS/test
24 |
25 | script:
26 | - cd $TRAVIS_BUILD_DIR/tests
27 | # build the target. This will call haxe with the HXFLAGS and HXFLAGS_EXTRA environment variables
28 | - haxe build.hxml
29 | - mono --debug bin/bin/CmdTests-Debug.exe
30 | - haxe build-unity.hxml
31 | - cp bin/bin/bin-Debug.dll ~/test.app/Contents/Data/Managed
32 | - cd ~
33 | - ./test.app/Contents/MacOS/test
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Cauê Waneck
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.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # unihx
2 | Unity-Haxe tools. Compile to Unity3D from Haxe.
3 |
4 | ## Goal
5 | Make Haxe be a first-class Unity development language, and make it easier to work with Haxe on Unity than the natively supported Unity languages
6 |
7 | ## Getting started
8 | Use `haxelib git unihx https://github.com/waneck/unihx.git` to install it.
9 |
10 | On an existing Unity project, run `haxelib run unihx init path/to/unity/proj`. Beware that you currently need a Haxe nightly build to be able to compile and use this library correctly.
11 |
12 | ## What works
13 | You can see a demonstration of some of its features at http://waneck.github.io/wwx-unity3d-haxe/ . The following are working already:
14 | * When Unity gets back to focus, it compiles the changed .hx scripts
15 | * You can click & drag .hx scripts into the inspector, like you can do with pure C#/UnityScript scripts
16 | * The resulting C# files are compiled in a directory relative to the .hx script file - so you can create Editor scripts, etc more easily
17 | * You can access other C# scripts from within Haxe, and vice-versa - even those that are compiled within the same compilation unit!
18 | * Access to any .NET library through `-net-lib`
19 | * Extend MonoBehaviour and code like you would with other Unity languages. Be sure to check the wwx presentation to get an idea of the types equivalence (e.g. C#'s array are cs.NativeArray in Haxe)
20 | * Use the `@:nativeGen` metadata to generate very clean code
21 | * Error positions always shown in the .hx code
22 | * Operator overloading on core structures like Vector2, Vector3, Matrix4x4, Quaternion, etc. See more about it at [Core Structures](https://github.com/waneck/unihx/wiki/Core-Structures)
23 |
24 | ## What still needs work
25 | * The HaxeBehaviour class is available, but some of its features demonstrated were proof-of-concept and are currently only accessible through the development branch.
26 |
27 | ## Help wanted
28 | Any kind of contribution will be much appreciated - from feature requests, testing it and adding bug reports, tutorials and documentation, to actual code and features!
29 | Pull requests are very welcome, and if you are excited as we are to bring an awesome Haxe support to Unity, let us know and join the team!
30 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | clone_folder: c:\projects\unihx
2 |
3 | environment:
4 | matrix:
5 | - TARGET: cs
6 |
7 | install: # clone travis-hx repo and setup the target
8 | - echo starting
9 | - git clone --depth=50 --branch=master git://github.com/waneck/travis-hx.git C:\travis-hx
10 | - C:\travis-hx\extra\appveyor\AppVeyor.exe setup
11 | - SET PATH=c:\HaxeToolkit\haxe;C:\HaxeToolkit\neko;C:\Program Files\7-Zip\;%PATH%
12 | - haxelib install utest
13 | - haxelib dev unihx C:\projects\unihx
14 | - cinst wget -x86
15 | - cd \projects\unihx\tests
16 | - wget "https://docs.google.com/uc?export=download&id=0B8FjDKR0nfqoTmZDWDNBTWtIYjA" -O win32.tar.gz --no-check-certificate
17 | - 7z x win32.tar.gz
18 | - 7z x win32.tar
19 |
20 | build_script:
21 | - cd \projects\unihx\tests
22 | - haxe build.hxml
23 | - bin\bin\CmdTests-Debug.exe
24 | - copy bin\bin\bin-Debug.dll test_Data\Managed
25 | - test.exe
26 |
--------------------------------------------------------------------------------
/assets/unihx-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/assets/unihx-logo.png
--------------------------------------------------------------------------------
/build-tool/build.hxml:
--------------------------------------------------------------------------------
1 | -cp src
2 | -neko ../run.n
3 | -main Cli
4 | -lib mcli
5 | -resource res/Template.hxproj@hxproj
6 |
--------------------------------------------------------------------------------
/build-tool/res/Template.hxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | haxe --cwd "$(ProjectDir)/Assets" classpaths.hxml params.hxml --macro unihx._internal.Compiler.compile\(\)
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/build-tool/src/Cli.hx:
--------------------------------------------------------------------------------
1 | import mcli.*;
2 | import sys.FileSystem.*;
3 | import haxe.io.Path;
4 | import haxe.Resource;
5 |
6 | using StringTools;
7 |
8 | class Cli extends CommandLine
9 | {
10 | /**
11 | Show this message.
12 | **/
13 | public function help()
14 | {
15 | Sys.println(this.showUsage());
16 | Sys.exit(0);
17 | }
18 |
19 | private function err(msg:String)
20 | {
21 | Sys.stderr().writeString(msg + "\n");
22 | Sys.exit(1);
23 | }
24 |
25 | private function haxe(args:Array)
26 | {
27 | print( 'haxe ' + [for (arg in args) arg.split('"').join('\\\"') ].join(" ") );
28 | var ret = Sys.command('haxe ' + [for (arg in args) arg.split('"').join('\\\"') ].join(" "));
29 | if (ret != 0)
30 | Sys.exit(ret);
31 | }
32 |
33 | /**
34 | Force always to yes
35 | **/
36 | public var force:Bool = false;
37 |
38 | public var verbose:Bool = false;
39 |
40 | private function print(msg:String)
41 | {
42 | if (verbose) Sys.println(msg);
43 | }
44 |
45 | private function ask(msg:String, ?preSelect:Bool):Bool
46 | {
47 | if (force) return true;
48 | Sys.println(msg);
49 | var stdin = Sys.stdin();
50 | var str = "(" + (preSelect == true ? "Y" : "y") + "/" + (preSelect == false ? "N" : "n") + ") ";
51 | while (true)
52 | {
53 | Sys.print(str);
54 | var ln = stdin.readLine().trim().toLowerCase();
55 | if (ln == "" && preSelect != null)
56 | return preSelect;
57 | else if (ln == "y")
58 | return true;
59 | else if (ln == "n")
60 | return false;
61 | }
62 | }
63 |
64 | public static function main()
65 | {
66 | var args = Sys.args();
67 | if (Sys.getEnv('HAXELIB_RUN') == "1")
68 | {
69 | var curpath = args.pop();
70 | Sys.setCwd(curpath);
71 | }
72 | new mcli.Dispatch(args).dispatch(new Helper());
73 | }
74 | }
75 |
76 | /**
77 | unihx helper tool
78 | **/
79 | class Helper extends CommandLine
80 | {
81 | /**
82 | Initializes the target Unity project to use unihx
83 | **/
84 | public function init(d:Dispatch)
85 | {
86 | d.dispatch(new InitCmd());
87 | }
88 | }
89 |
90 | /**
91 | unihx init [target-dir] : initializes the target Unity project to use unihx.
92 | **/
93 | class InitCmd extends Cli
94 | {
95 | public function runDefault(targetDir=".")
96 | {
97 | if (!exists(targetDir))
98 | {
99 | err('"$targetDir" does not exist');
100 | }
101 |
102 | if (targetDir == "")
103 | targetDir = ".";
104 | // look for 'Assets' folder
105 | var assets = getAssets(targetDir);
106 | if (assets == null)
107 | {
108 | err('Cannot find the Assets folder at "$targetDir"');
109 | }
110 | if (assets == "")
111 | assets = ".";
112 |
113 | if (!exists(assets + "/classpaths.hxml"))
114 | {
115 | sys.io.File.saveContent(assets + '/classpaths.hxml', '#this file is automatically generated. any change made here may be lost\n-cp .\n-cp Scripts');
116 | }
117 |
118 | if (!exists(assets + "/build.hxml"))
119 | {
120 | sys.io.File.saveContent(assets + '/build.hxml', 'params.hxml\n# Add your own compiler parameters here\n');
121 | }
122 |
123 | if (!exists(assets + '/params.hxml') || ask('$targetDir/params.hxml already exists. Replace?',true))
124 | {
125 | sys.io.File.saveContent(assets + '/params.hxml', 'classpaths.hxml\n-lib unihx\n-cs hx-compiled\n-D unity_std_target=Standard Assets');
126 | var old = Sys.getCwd();
127 | Sys.setCwd(assets);
128 | if (Sys.systemName() == "Windows")
129 | haxe(['params.hxml',"--macro","include(\"unihx._internal.editor\")"]);
130 | else
131 | haxe(['params.hxml',"--macro","include\\(\"unihx._internal.editor\"\\)"]);
132 | Sys.setCwd(old);
133 | }
134 |
135 | var proj = assets + "/../" + Path.withoutDirectory( fullPath(assets + "/..") ) + '.hxproj';
136 | if (!exists(proj))
137 | {
138 | sys.io.File.saveContent(proj, Resource.getString("hxproj"));
139 | }
140 |
141 | for (f in ['smcs','gmcs'])
142 | {
143 | if (!exists(assets + '/$f.rsp'))
144 | {
145 | sys.io.File.saveContent(assets+'/$f.rsp', "-nowarn:0109,0114,0219,0429,0168,0162");
146 | }
147 | }
148 |
149 | }
150 |
151 | private function getAssets(dir:String):Null
152 | {
153 | var full = fullPath(dir).split('\\').join('/').split('/');
154 | while (full[full.length-1] == "")
155 | full.pop();
156 |
157 | var buf = new StringBuf();
158 | buf.add(".");
159 | while (full.length > 1)
160 | {
161 | var dir = full.join('/');
162 | for (file in readDirectory(dir))
163 | {
164 | if (file == "Assets")
165 | return buf + '/Assets';
166 | }
167 | buf.add('/..');
168 | full.pop();
169 | }
170 | return null;
171 | }
172 |
173 | }
174 |
--------------------------------------------------------------------------------
/extraParams.hxml:
--------------------------------------------------------------------------------
1 | -net-lib lib/UnityEngine.dll
2 | -net-lib lib/UnityEditor.dll
3 | -D use_rtti_doc
4 |
--------------------------------------------------------------------------------
/haxe/Log.hx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C)2005-2012 Haxe Foundation
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a
5 | * copy of this software and associated documentation files (the "Software"),
6 | * to deal in the Software without restriction, including without limitation
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 | * and/or sell copies of the Software, and to permit persons to whom the
9 | * Software is furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 | * DEALINGS IN THE SOFTWARE.
21 | */
22 | package haxe;
23 |
24 | /**
25 | Log primarily provides the trace() method, which is invoked upon a call to
26 | trace() in haxe code.
27 | **/
28 | class Log {
29 |
30 | /**
31 | Outputs `v` in a platform-dependent way.
32 |
33 | The second parameter `infos` is injected by the compiler and contains
34 | information about the position where the trace() call was made.
35 |
36 | This method can be rebound to a custom function:
37 | var oldTrace = haxe.Log.trace; // store old function
38 | haxe.Log.trace = function(v,infos) { // handle trace }
39 | ...
40 | haxe.Log.trace = oldTrace;
41 |
42 | If it is bound to null, subsequent calls to trace() will cause an
43 | exception.
44 | **/
45 | public static dynamic function trace( v : Dynamic, ?infos : PosInfos ) : Void {
46 | #if flash
47 | #if (fdb || native_trace)
48 | var pstr = infos == null ? "(null)" : infos.fileName + ":" + infos.lineNumber;
49 | var str = flash.Boot.__string_rec(v, "");
50 | if( infos != null && infos.customParams != null ) for( v in infos.customParams ) str += "," + flash.Boot.__string_rec(v, "");
51 | untyped #if flash9 __global__["trace"] #else __trace__ #end(pstr+": "+str);
52 | #else
53 | untyped flash.Boot.__trace(v,infos);
54 | #end
55 | #elseif neko
56 | untyped {
57 | $print(infos.fileName + ":" + infos.lineNumber + ": ", v);
58 | if( infos.customParams != null ) for( v in infos.customParams ) $print(",", v);
59 | $print("\n");
60 | }
61 | #elseif js
62 | untyped js.Boot.__trace(v,infos);
63 | #elseif php
64 | if (infos!=null && infos.customParams!=null) {
65 | var extra:String = "";
66 | for( v in infos.customParams )
67 | extra += "," + v;
68 | untyped __call__('_hx_trace', v + extra, infos);
69 | }
70 | else
71 | untyped __call__('_hx_trace', v, infos);
72 | #elseif cpp
73 | if (infos!=null && infos.customParams!=null) {
74 | var extra:String = "";
75 | for( v in infos.customParams )
76 | extra += "," + v;
77 | untyped __trace(v + extra,infos);
78 | }
79 | else
80 | untyped __trace(v,infos);
81 | #elseif (cs || java)
82 | var str:String = null;
83 | if (infos != null) {
84 | str = infos.fileName + ":" + infos.lineNumber + ": " + v;
85 | if (infos.customParams != null)
86 | {
87 | str += "," + infos.customParams.join(",");
88 | }
89 | } else {
90 | str = v;
91 | }
92 | #if cs
93 | // cs.system.Console.WriteLine(str);
94 | unityengine.Debug.Log(str);
95 | #elseif java
96 | untyped __java__("java.lang.System.out.println(str)");
97 | #end
98 | #end
99 | }
100 |
101 | #if (flash || js)
102 | /**
103 | Clears the trace output.
104 | **/
105 | public static dynamic function clear() : Void {
106 | #if flash
107 | untyped flash.Boot.__clear_trace();
108 | #elseif js
109 | untyped js.Boot.__clear_trace();
110 | #end
111 | }
112 | #end
113 |
114 | #if flash
115 | /**
116 | Sets the color of the trace output to `rgb`.
117 | **/
118 | public static dynamic function setColor( rgb : Int ) {
119 | untyped flash.Boot.__set_trace_color(rgb);
120 | }
121 | #end
122 |
123 | }
124 |
--------------------------------------------------------------------------------
/haxe/Timer.hx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2005, The haXe Project Contributors
3 | * All rights reserved.
4 | * Redistribution and use in source and binary forms, with or without
5 | * modification, are permitted provided that the following conditions are met:
6 | *
7 | * - Redistributions of source code must retain the above copyright
8 | * notice, this list of conditions and the following disclaimer.
9 | * - Redistributions in binary form must reproduce the above copyright
10 | * notice, this list of conditions and the following disclaimer in the
11 | * documentation and/or other materials provided with the distribution.
12 | *
13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
23 | * DAMAGE.
24 | */
25 | package haxe;
26 | #if cs
27 | import cs.system.DateTime;
28 | import cs.system.Object;
29 | import cs.system.timers.ElapsedEventArgs;
30 | import cs.system.timers.ElapsedEventHandler;
31 | import cs.system.TimeSpan;
32 | #end
33 | /**
34 | The Timer class allows you to create asynchronous timers on platforms that support events.
35 | **/
36 | class Timer {
37 |
38 | #if (neko || php || cpp)
39 | #else
40 | #if cs
41 | private var t:cs.system.timers.Timer;
42 | private var id : Null;
43 | private function runRun():Void run();
44 | #end
45 | /**
46 | Create a new timer that will run every [time_ms] (in milliseconds).
47 | **/
48 | public function new( time_ms : Int ) {
49 | #if cs
50 | id = 1;
51 | var f = runRun;
52 | var tt = t = new cs.system.timers.Timer(time_ms);
53 | t.Enabled = true;
54 | untyped __cs__("tt.Elapsed+=delegate(System.Object o, System.Timers.ElapsedEventArgs e){f.__hx_invoke0_o();}");
55 | #elseif flash9
56 | var me = this;
57 | id = untyped __global__["flash.utils.setInterval"](function() { me.run(); },time_ms);
58 | #elseif flash
59 | var me = this;
60 | id = untyped _global["setInterval"](function() { me.run(); },time_ms);
61 | #elseif js
62 | var me = this;
63 | id = untyped window.setInterval(function() me.run(),time_ms);
64 | #end
65 | }
66 |
67 | /**
68 | Stop the timer definitely.
69 | **/
70 | public function stop() {
71 | if( id == null )
72 | return;
73 | #if cs
74 | t.Stop();
75 | t.Enabled = false;
76 | t = null;
77 | #elseif flash9
78 | untyped __global__["flash.utils.clearInterval"](id);
79 | #elseif flash
80 | untyped _global["clearInterval"](id);
81 | #elseif js
82 | untyped window.clearInterval(id);
83 | #end
84 | id = null;
85 | }
86 |
87 | /**
88 | This is the [run()] method that is called when the Timer executes. It can be either overriden in subclasses or directly rebinded with another function-value.
89 | **/
90 | public dynamic function run() {
91 | trace("run");
92 | }
93 |
94 | /**
95 | This will delay the call to [f] for the given time. [f] will only be called once.
96 | **/
97 | public static function delay( f : Void -> Void, time_ms : Int ) {
98 | var t = new haxe.Timer(time_ms);
99 | t.run = function() {
100 | t.stop();
101 | f();
102 | };
103 | return t;
104 | }
105 |
106 | #end
107 |
108 | /**
109 | Measure the time it takes to execute the function [f] and trace it. Returns the value returned by [f].
110 | **/
111 | public static function measure( f : Void -> T, ?pos : PosInfos ) : T {
112 | var t0 = stamp();
113 | var r = f();
114 | Log.trace((stamp() - t0) + "s", pos);
115 | return r;
116 | }
117 |
118 | /**
119 | Returns the most precise timestamp, in seconds. The value itself might differ depending on platforms, only differences between two values make sense.
120 | **/
121 | public static function stamp() : Float {
122 | #if cs
123 | var ts:TimeSpan = null;
124 | ts = untyped __cs__('System.DateTime.UtcNow - new System.DateTime(1970, 1, 1)');
125 | return ts.TotalMilliseconds;
126 | #elseif flash
127 | return flash.Lib.getTimer() / 1000;
128 | #elseif (neko || php)
129 | return Sys.time();
130 | #elseif js
131 | return Date.now().getTime() / 1000;
132 | #elseif cpp
133 | return untyped __global__.__time_stamp();
134 | #else
135 | return 0;
136 | #end
137 | }
138 |
139 | }
140 |
--------------------------------------------------------------------------------
/lib/Unity.CecilTools.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/lib/Unity.CecilTools.dll
--------------------------------------------------------------------------------
/lib/Unity.DataContract.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/lib/Unity.DataContract.dll
--------------------------------------------------------------------------------
/lib/Unity.IvyParser.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/lib/Unity.IvyParser.dll
--------------------------------------------------------------------------------
/lib/Unity.Locator.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/lib/Unity.Locator.dll
--------------------------------------------------------------------------------
/lib/Unity.SerializationLogic.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/lib/Unity.SerializationLogic.dll
--------------------------------------------------------------------------------
/lib/UnityEditor.Graphs.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/lib/UnityEditor.Graphs.dll
--------------------------------------------------------------------------------
/lib/UnityEditor.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/lib/UnityEditor.dll
--------------------------------------------------------------------------------
/lib/UnityEngine.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/lib/UnityEngine.dll
--------------------------------------------------------------------------------
/run.n:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/run.n
--------------------------------------------------------------------------------
/tests/build-unity.hxml:
--------------------------------------------------------------------------------
1 | -cp src
2 | -lib unihx
3 | -lib utest
4 | -debug
5 | -cs bin
6 | -D dll
7 | UnityTests
8 |
--------------------------------------------------------------------------------
/tests/build.hxml:
--------------------------------------------------------------------------------
1 | -cp src
2 | -main CmdTests
3 | -lib unihx
4 | -lib utest
5 | -debug
6 | -cs bin
7 |
--------------------------------------------------------------------------------
/tests/project/.gitignore:
--------------------------------------------------------------------------------
1 | # =============== #
2 | # Unity generated #
3 | # =============== #
4 | Temp/
5 | Obj/
6 | UnityGenerated/
7 | Library/
8 |
9 | # ===================================== #
10 | # Visual Studio / MonoDevelop generated #
11 | # ===================================== #
12 | ExportedObj/
13 | *.svd
14 | *.userprefs
15 | *.csproj
16 | *.pidb
17 | *.suo
18 | *.sln
19 | *.user
20 | *.unityproj
21 | *.booproj
22 |
23 | # ============ #
24 | # OS generated #
25 | # ============ #
26 | .DS_Store
27 | .DS_Store?
28 | ._*
29 | .Spotlight-V100
30 | .Trashes
31 | Icon?
32 | ehthumbs.db
33 | Thumbs.db
34 |
--------------------------------------------------------------------------------
/tests/project/Assets/TestEntryPoint.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 |
4 | public class TestEntryPoint : MonoBehaviour {
5 |
6 | // Use this for initialization
7 | void Start () {
8 | UnityTests.runTests(delegate(bool passed) {
9 | Debug.Log(passed);
10 | });
11 | }
12 |
13 | // Update is called once per frame
14 | void Update () {
15 |
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/project/Assets/TestEntryPoint.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 635e032aec4370446a139dea98aa90c2
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/tests/project/Assets/TestScene.unity:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/Assets/TestScene.unity
--------------------------------------------------------------------------------
/tests/project/Assets/TestScene.unity.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d856d7b17ab19f543aa870627c0cfaf6
3 | DefaultImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/tests/project/Assets/bin-Debug.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/Assets/bin-Debug.dll
--------------------------------------------------------------------------------
/tests/project/Assets/bin-Debug.dll.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: feaad69e28992a84dbacb73b95c5b475
3 | MonoAssemblyImporter:
4 | serializedVersion: 1
5 | iconMap: {}
6 | executionOrder: {}
7 | userData:
8 |
--------------------------------------------------------------------------------
/tests/project/ProjectSettings/AudioManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/ProjectSettings/AudioManager.asset
--------------------------------------------------------------------------------
/tests/project/ProjectSettings/DynamicsManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/ProjectSettings/DynamicsManager.asset
--------------------------------------------------------------------------------
/tests/project/ProjectSettings/EditorBuildSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/ProjectSettings/EditorBuildSettings.asset
--------------------------------------------------------------------------------
/tests/project/ProjectSettings/EditorSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/ProjectSettings/EditorSettings.asset
--------------------------------------------------------------------------------
/tests/project/ProjectSettings/GraphicsSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/ProjectSettings/GraphicsSettings.asset
--------------------------------------------------------------------------------
/tests/project/ProjectSettings/InputManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/ProjectSettings/InputManager.asset
--------------------------------------------------------------------------------
/tests/project/ProjectSettings/NavMeshLayers.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/ProjectSettings/NavMeshLayers.asset
--------------------------------------------------------------------------------
/tests/project/ProjectSettings/NetworkManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/ProjectSettings/NetworkManager.asset
--------------------------------------------------------------------------------
/tests/project/ProjectSettings/Physics2DSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/ProjectSettings/Physics2DSettings.asset
--------------------------------------------------------------------------------
/tests/project/ProjectSettings/ProjectSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/ProjectSettings/ProjectSettings.asset
--------------------------------------------------------------------------------
/tests/project/ProjectSettings/QualitySettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/ProjectSettings/QualitySettings.asset
--------------------------------------------------------------------------------
/tests/project/ProjectSettings/TagManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/ProjectSettings/TagManager.asset
--------------------------------------------------------------------------------
/tests/project/ProjectSettings/TimeManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waneck/unihx/b2e19c69926ea072de07f7de7c59ee4f86464502/tests/project/ProjectSettings/TimeManager.asset
--------------------------------------------------------------------------------
/tests/src/CmdTests.hx:
--------------------------------------------------------------------------------
1 | import utest.Runner;
2 | import utest.ui.Report;
3 |
4 | class CmdTests
5 | {
6 | static function main()
7 | {
8 | // var ret = sys.io.File.write('test.txt');
9 | haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos) {
10 | var str:String = null;
11 | if (infos != null) {
12 | str = infos.fileName + ":" + infos.lineNumber + ": " + v;
13 | if (infos.customParams != null)
14 | {
15 | str += "," + infos.customParams.join(",");
16 | }
17 | } else {
18 | str = v;
19 | }
20 | // ret.writeString(str);
21 | // ret.writeString('\n');
22 | cs.system.Console.WriteLine(str);
23 | };
24 | var runner = new Runner();
25 |
26 | runner.addCase(new tests.YieldTests());
27 |
28 | var report = new utest.ui.text.PrintReport(runner);
29 | runner.run();
30 |
31 | // ret.close();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/src/UnityTests.hx:
--------------------------------------------------------------------------------
1 | import utest.Runner;
2 | import utest.ui.Report;
3 |
4 | class UnityTests
5 | {
6 | static function runTests(onEnd:cs.system.Action_1)
7 | {
8 | // var ret = sys.io.File.write('test.txt');
9 | haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos) {
10 | var str:String = null;
11 | if (infos != null) {
12 | str = infos.fileName + ":" + infos.lineNumber + ": " + v;
13 | if (infos.customParams != null)
14 | {
15 | str += "," + infos.customParams.join(",");
16 | }
17 | } else {
18 | str = v;
19 | }
20 | // ret.writeString(str);
21 | // ret.writeString('\n');
22 | cs.system.Console.WriteLine(str);
23 | };
24 | var runner = new Runner();
25 |
26 | runner.addCase(new tests.YieldTests());
27 |
28 | var report = new utest.ui.text.PrintReport(runner);
29 | runner.run();
30 |
31 | // ret.close();
32 | unityengine.Application.Quit();
33 | onEnd.Invoke(true);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/src/tests/YieldTests.hx:
--------------------------------------------------------------------------------
1 | package tests;
2 | import utest.Assert;
3 | import unihx._internal.YieldBase;
4 |
5 | using Lambda;
6 |
7 | class YieldTests
8 | {
9 | public function new()
10 | {
11 | this.someTest = "someTest";
12 | }
13 |
14 | private var someTest:String;
15 |
16 | macro private static function test(expr:haxe.macro.Expr):haxe.macro.Expr.ExprOf
17 | {
18 | var ret = unihx._internal.YieldGenerator.make('tests.unihx',expr);
19 | return macro ($ret : unihx._internal.YieldBase);
20 | }
21 |
22 | macro private static function fails(e:haxe.macro.Expr)
23 | {
24 | try
25 | {
26 | haxe.macro.Context.typeof(e);
27 | return macro false;
28 | }
29 | catch(e:Dynamic) {
30 | return macro true;
31 | }
32 | }
33 |
34 | #if !macro
35 | public function test_basic()
36 | {
37 | var t1 = test({
38 | var a:Array = [];
39 | {
40 | a.push(1);
41 | {
42 | @yield {retn:"A",arr:a};
43 | a.push(1.1);
44 | }
45 | {
46 | a.push(1.2);
47 | @yield {retn:"B",arr:a};
48 | a.push(1.3);
49 | a = [];
50 | }
51 | a.push(2);
52 | @yield {retn:"b",arr:a};
53 | a.push(3);
54 | }
55 | @yield {retn:"c",arr:a};
56 | a.push(4);
57 | });
58 | Assert.isTrue(t1.hasNext());
59 | Assert.same({retn:"A",arr:[1]}, t1.next());
60 | Assert.isTrue(t1.hasNext());
61 | Assert.same({retn:"B",arr:[1,1.1,1.2]}, t1.next());
62 | Assert.isTrue(t1.hasNext());
63 | Assert.same({retn:"b",arr:[2]}, t1.next());
64 | Assert.isTrue(t1.hasNext());
65 | var last = t1.next();
66 | Assert.same({retn:"c",arr:[2,3]}, last);
67 | Assert.isFalse(t1.hasNext());
68 | Assert.same([2,3,4],last.arr);
69 | }
70 |
71 | public function test_if()
72 | {
73 | var t = true, f = false;
74 | var t1 = test({
75 | var a:Array = [];
76 | if (t)
77 | {
78 | a.push(1);
79 | if (true)
80 | {
81 | @yield {retn:"A",arr:a};
82 | a.push(1.1);
83 | }
84 | if (f)
85 | {
86 | a.push(-2);
87 | @yield {retn:"-a",arr:a};
88 | a.push(-3);
89 | } else {
90 | a.push(1.2);
91 | @yield {retn:"B",arr:a};
92 | a.push(1.3);
93 | }
94 | a = [];
95 | a.push(2);
96 | @yield {retn:"b",arr:a};
97 | a.push(3);
98 | }
99 | @yield {retn:"c",arr:a};
100 | a.push(4);
101 | });
102 |
103 | Assert.isTrue(t1.hasNext());
104 | f = true; //it shouldn't change the behavior here - as vars aren't captured, they are copied
105 | Assert.same({retn:"A",arr:[1]}, t1.next());
106 | Assert.isTrue(t1.hasNext());
107 | Assert.same({retn:"B",arr:[1,1.1,1.2]}, t1.next());
108 | Assert.isTrue(t1.hasNext());
109 | Assert.same({retn:"b",arr:[2]}, t1.next());
110 | Assert.isTrue(t1.hasNext());
111 | var last = t1.next();
112 | Assert.same({retn:"c",arr:[2,3]}, last);
113 | Assert.isFalse(t1.hasNext());
114 | Assert.same([2,3,4],last.arr);
115 |
116 | //check for deep nesting
117 | var t = true, f = false;
118 | var t1 = test({
119 | var a:Array = [];
120 | if (t)
121 | {
122 | a.push(1);
123 | if (true)
124 | {
125 | @yield {retn:"A",arr:a};
126 | a.push(1.1);
127 | }
128 | if (f)
129 | {
130 | a.push(-2);
131 | @yield {retn:"-a",arr:a};
132 | a.push(-3);
133 | if (f)
134 | {
135 | a.push(-4);
136 | @yield null;
137 | a.push(-5);
138 | } else if (false) {
139 | a.push(-6);
140 | @yield null;
141 | if (true)
142 | {
143 | a.push(-6.1);
144 | @yield null;
145 | a.push(-6.2);
146 | }
147 | a.push(-7);
148 | @yield null;
149 | a.push(-8);
150 | } else {
151 | a.push(-9);
152 | @yield null;
153 | a.push(-10);
154 | }
155 | } else {
156 | if (t)
157 | {
158 | a.push(1.11);
159 | @yield {retn:"A1",arr:a};
160 | a.push(1.12);
161 | } else {
162 | a.push(-11);
163 | @yield null;
164 | a.push(-12);
165 | }
166 | a.push(1.2);
167 | @yield {retn:"B",arr:a};
168 | a.push(1.3);
169 | }
170 | a = [];
171 | //test now first true, then false
172 | if (t)
173 | {
174 | a.push(1.4);
175 | @yield {retn:"B1",arr:a};
176 | a.push(1.5);
177 | @yield {retn:"B2",arr:a};
178 | } else if (f) {
179 | a.push(-4);
180 | @yield null;
181 | a.push(-5);
182 | } else {
183 | a.push(-6);
184 | @yield null;
185 | if (true)
186 | {
187 | a.push(-6.1);
188 | @yield null;
189 | a.push(-6.2);
190 | }
191 | a.push(-7);
192 | @yield null;
193 | a.push(-8);
194 | }
195 | a = [];
196 | a.push(2);
197 | @yield {retn:"b",arr:a};
198 | a.push(3);
199 | }
200 | @yield {retn:"c",arr:a};
201 | a.push(4);
202 | });
203 |
204 | Assert.isTrue(t1.hasNext());
205 | Assert.same({retn:"A",arr:[1]}, t1.next());
206 | Assert.isTrue(t1.hasNext());
207 | Assert.same({retn:"A1",arr:[1,1.1,1.11]}, t1.next());
208 | Assert.isTrue(t1.hasNext());
209 | Assert.same({retn:"B",arr:[1,1.1,1.11,1.12,1.2]}, t1.next());
210 | Assert.isTrue(t1.hasNext());
211 | Assert.same({retn:"B1",arr:[1.4]}, t1.next());
212 | Assert.isTrue(t1.hasNext());
213 | Assert.same({retn:"B2",arr:[1.4,1.5]}, t1.next());
214 | Assert.isTrue(t1.hasNext());
215 | Assert.same({retn:"b",arr:[2]}, t1.next());
216 | Assert.isTrue(t1.hasNext());
217 | var last = t1.next();
218 | Assert.same({retn:"c",arr:[2,3]}, last);
219 | Assert.isFalse(t1.hasNext());
220 | Assert.same([2,3,4],last.arr);
221 | }
222 |
223 | public function test_fibonacci()
224 | {
225 | //returns the 10 first fibonacci numbers
226 | var fib = test({
227 | var an2 = 0, an1 = 1;
228 | @yield 0; @yield 1;
229 | for (i in 0...8)
230 | {
231 | var c = an1 + an2;
232 | an2 = an1; an1 = c;
233 | @yield c;
234 | }
235 | });
236 |
237 | Assert.same([0,1, 1, 2, 3, 5, 8, 13, 21, 34], [for(v in fib) v]);
238 |
239 | //infinite version
240 | var fib = test({
241 | var an2 = 0, an1 = 1;
242 | @yield 0; @yield 1;
243 | while(true)
244 | {
245 | var c = an1 + an2;
246 | an2 = an1; an1 = c;
247 | @yield c;
248 | }
249 | });
250 |
251 | for (i in [0,1, 1, 2, 3, 5, 8, 13, 21, 34])
252 | {
253 | Assert.isTrue(fib.hasNext());
254 | Assert.equals(i,fib.next());
255 | }
256 | Assert.isTrue(fib.hasNext());
257 | }
258 |
259 | public function test_fact()
260 | {
261 | //first 10 factorial numbers
262 | var fact = test({
263 | var acc = 1;
264 | @yield 1;
265 | for (i in 1...10)
266 | {
267 | @yield (acc *= i);
268 | }
269 | });
270 |
271 | Assert.same([1,1,2,6,24,120,720,5040,40320,362880], [for(v in fact) v]);
272 |
273 | //infinite version
274 | var fact = test({
275 | var acc = 1, i = 1;
276 | @yield 1;
277 | while(true)
278 | {
279 | @yield (acc *= i++);
280 | }
281 | });
282 |
283 | for (i in [1,1,2,6,24,120,720,5040,40320,362880])
284 | {
285 | Assert.isTrue(fact.hasNext());
286 | Assert.equals(i,fact.next());
287 | }
288 | Assert.isTrue(fact.hasNext());
289 | }
290 |
291 | public function test_array_for()
292 | {
293 | var t = test({
294 | var arr = [1,2,3,4,5,6,7], lastValue = -1;
295 | for (a in arr)
296 | {
297 | var myval = a + lastValue;
298 | lastValue = a;
299 | @yield myval;
300 | }
301 | });
302 | for (i in [0, 3, 5, 7, 9, 11, 13])
303 | {
304 | Assert.isTrue(t.hasNext());
305 | Assert.equals(i, t.next());
306 | }
307 |
308 | //calling iterator() directly
309 | var t = test({
310 | var arr = [1,2,3,4,5,6,7], lastValue = -1;
311 | for (a in arr.iterator())
312 | {
313 | var myval = a + lastValue;
314 | lastValue = a;
315 | @yield myval;
316 | }
317 | });
318 | for (i in [0, 3, 5, 7, 9, 11, 13])
319 | {
320 | Assert.isTrue(t.hasNext());
321 | Assert.equals(i, t.next());
322 | }
323 | }
324 |
325 | public function test_list_for()
326 | {
327 | var t = test({
328 | var arr = [1,2,3,4,5,6,7].list(), lastValue = -1;
329 | for (a in arr)
330 | {
331 | var myval = a + lastValue;
332 | @yield myval;
333 | lastValue = a;
334 | }
335 | });
336 | for (i in [0, 3, 5, 7, 9, 11, 13])
337 | {
338 | Assert.isTrue(t.hasNext());
339 | Assert.equals(i, t.next());
340 | }
341 | var t = test({
342 | var arr = [1,2,3,4,5,6,7].list(), lastValue = -1;
343 | for (a in arr.iterator())
344 | {
345 | var myval = a + lastValue;
346 | lastValue = a;
347 | @yield myval;
348 | }
349 | });
350 | for (i in [0, 3, 5, 7, 9, 11, 13])
351 | {
352 | Assert.isTrue(t.hasNext());
353 | Assert.equals(i, t.next());
354 | }
355 |
356 | }
357 |
358 | public function test_while()
359 | {
360 | for (rand in [true,false])
361 | {
362 | var t = true, f = false;
363 | var t = test({
364 | var i = 10, a = [1.];
365 | while(++i < 15)
366 | {
367 | a.push(i / 10);
368 | if(t)
369 | {
370 | a.push(2);
371 | if (true)
372 | {
373 | @yield {retn:1, arr:a};
374 | if(rand)
375 | a.push(2.05);
376 | }
377 | if (f)
378 | {
379 | a.push(-2);
380 | @yield {retn:-1,arr:a};
381 | a.push(-3);
382 | if (f)
383 | {
384 | a.push(-4);
385 | @yield null;
386 | a.push(-5);
387 | } else if (false) {
388 | a.push(-6);
389 | for(i in 0...10)
390 | @yield null;
391 | if (true)
392 | {
393 | a.push(-6.1);
394 | do
395 | {
396 | @yield null;
397 | } while(--i > 0);
398 | a.push(-6.2);
399 | }
400 | a.push(-7);
401 | @yield null;
402 | a.push(-8);
403 | } else {
404 | a.push(-9);
405 | @yield null;
406 | a.push(-10);
407 | }
408 | } else {
409 | if (t)
410 | {
411 | a.push(2.10);
412 | @yield {retn:2, arr:a};
413 | if (rand)
414 | a.push(2.15);
415 | } else {
416 | a.push(-11);
417 | @yield null;
418 | a.push(-12);
419 | }
420 | a.push(2.2);
421 | @yield {retn:3, arr:a};
422 | var j = 3;
423 | do
424 | {
425 | a.push(2 + j / 10);
426 | @yield {retn:j+1, arr:a};
427 | if (rand)
428 | a.push(2 + j / 10 + .05);
429 | } while(++j < 6);
430 | a.push(2.6);
431 | }
432 | a = [];
433 | if(t)
434 | {
435 | a.push(3);
436 | @yield {retn:7, arr:a};
437 | var j = 0;
438 | while(++j < 3)
439 | {
440 | a.push(3 + j / 10);
441 | @yield {retn:7 + j, arr:a};
442 | }
443 | } else if (f) {
444 | a.push(-4);
445 | @yield null;
446 | a.push(-5);
447 | } else {
448 | a.push(-6);
449 | @yield null;
450 | if (true)
451 | {
452 | a.push(-7);
453 | @yield null;
454 | a.push(-8);
455 | }
456 | a.push(-9);
457 | @yield null;
458 | a.push(-10);
459 | }
460 | a = [];
461 | a.push(4);
462 | var j = 0;
463 | do
464 | {
465 | @yield {retn:10 + j, arr:a};
466 | a.push(4 + j / 10);
467 | if (rand)
468 | a.push(4 + j / 10 + .05);
469 | } while(++j < 4);
470 | }
471 | @yield {retn:14, arr:a};
472 | a.push(5);
473 | }
474 | });
475 |
476 | // var answers =
477 | var i = 10,
478 | a = [1.];
479 | inline function getValue() return t.hasNext() ? t.next() : null;
480 |
481 | for (i in 11...15)
482 | {
483 | a.push(i / 10);
484 | a.push(2);
485 | Assert.same({ retn:1, arr: a }, getValue());
486 | if (rand) a.push(2.05);
487 | a.push(2.10);
488 | Assert.same({ retn:2, arr: a }, getValue());
489 | if (rand) a.push(2.15);
490 | a.push(2.2);
491 | Assert.same({ retn:3, arr : a}, getValue());
492 | a.push(2.3);
493 | Assert.same({ retn:4, arr : a}, getValue());
494 | if (rand) a.push(2.35);
495 | a.push(2.4);
496 | Assert.same({ retn:5, arr : a}, getValue());
497 | if (rand) a.push(2.45);
498 | a.push(2.5);
499 | Assert.same({ retn:6, arr : a}, getValue());
500 | a.push(2.6);
501 | a = [3];
502 | Assert.same({ retn:7, arr : a}, getValue());
503 | a.push(3.1);
504 | Assert.same({ retn:8, arr : a}, getValue());
505 | a.push(3.2);
506 | Assert.same({ retn:9, arr : a}, getValue());
507 | a = [4];
508 | Assert.same({ retn:10, arr : a}, getValue());
509 | for (i in 0...4)
510 | {
511 | a.push(4 + i / 10);
512 | if (rand) a.push(4 + i / 10 + .05);
513 | Assert.same({ retn:11 + i, arr : a}, getValue());
514 | }
515 | a.push(5);
516 | // Assert.same({ retn: 12, arr : a}, getValue());
517 | }
518 | // for (v in t)
519 | // trace(v);
520 | }
521 | }
522 |
523 | public function test_pat_match()
524 | {
525 | var expr = macro 10 + 20 + 60 - 10;
526 | var t = test({
527 | var acc = 0;
528 | while(true)
529 | {
530 | switch(expr.expr)
531 | {
532 | case EBinop(op,{ expr:EConst(CInt(x)) },{ expr:EConst(CInt(y)) }):
533 | acc += Std.parseInt(x);
534 | acc += Std.parseInt(y);
535 | @yield { op:op + "", acc:acc, v:2 };
536 | break;
537 | case EBinop(op,e1,{ expr:EConst(CInt(x)) }):
538 | acc += Std.parseInt(x);
539 | @yield { op:op + "", acc:acc, v:1 };
540 | expr = e1;
541 | case _:
542 | throw "argh: " + expr;
543 | }
544 | }
545 | });
546 | inline function getValue() return t.hasNext() ? t.next() : null;
547 |
548 | Assert.same({ op:"OpSub", acc:10, v:1 }, getValue());
549 | Assert.same({ op:"OpAdd", acc:70, v:1 }, getValue());
550 | Assert.same({ op:"OpAdd", acc:100, v:2 }, getValue());
551 | Assert.isFalse(t.hasNext());
552 |
553 | expr = macro @:someMeta 50 + 5 - 10 + 20 + 60 - 10;
554 | t = test({
555 | var acc = 0;
556 | while(true)
557 | {
558 | switch(expr.expr)
559 | {
560 | case EBinop(op,{ expr:EConst(CInt(x)) },{ expr:EConst(CInt(y)) }):
561 | acc += Std.parseInt(x);
562 | acc += Std.parseInt(y);
563 | @yield { op:op + "", acc:acc, v:2 };
564 | break;
565 | case EBinop(op,e1 = { expr:EBinop(_,_,_) },{ expr:EConst(CInt(x)) }):
566 | acc += Std.parseInt(x);
567 | @yield { op:op + "", acc:acc, v:1 };
568 | expr = e1;
569 | case EBinop(op,e1,e2):
570 | acc += 5;
571 | @yield { op:"no const", acc:acc, v:0 };
572 | switch(e1)
573 | {
574 | case macro notHere:
575 | acc -= 10;
576 | case macro @:someMeta $v:
577 | switch(v.expr) {
578 | case EConst(CInt(x)):
579 | @yield { acc:acc, v:3 };
580 | acc += Std.parseInt(x);
581 | @yield { acc:acc, v:4 };
582 | case _:
583 | acc -= 100;
584 | @yield acc;
585 | acc -= 90;
586 | @yield acc;
587 | }
588 | case _:
589 | acc = 4;
590 | @yield false;
591 | trace(acc);
592 | @yield acc;
593 | acc -= 10;
594 | }
595 | acc += 5;
596 | @yield { op:"finished", acc:acc, v:5 };
597 | switch (e2) {
598 | case { expr: EConst(CInt(x)) }:
599 | @yield { acc:acc, v:6 };
600 | acc += Std.parseInt(x);
601 | @yield { acc:acc, v:7 };
602 | acc = Std.parseInt(x);
603 | case _:
604 | acc = 0;
605 | @yield false;
606 | trace(acc);
607 | @yield acc;
608 | acc -= 10;
609 | }
610 | @yield { op:op + "", acc:acc, v:8 };
611 | break;
612 | @yield { op:op + "", acc:acc, v:9 };
613 | case _:
614 | throw "shouldnt be here: " + expr;
615 | }
616 | }
617 | });
618 | inline function getValue() return t.hasNext() ? t.next() : null;
619 |
620 | Assert.same({ op:"OpSub", acc:10, v:1 }, getValue());
621 | Assert.same({ op:"OpAdd", acc:70, v:1 }, getValue());
622 | Assert.same({ op:"OpAdd", acc:90, v:1 }, getValue());
623 | Assert.same({ op:"OpSub", acc:100, v:1 }, getValue());
624 | Assert.same({ op:"no const", acc:105, v:0 }, getValue());
625 | Assert.same({ acc:105, v:3 }, getValue());
626 | Assert.same({ acc:155, v:4 }, getValue());
627 | Assert.same({ op:"finished", acc:160, v:5 }, getValue());
628 | Assert.same({ acc:160, v:6 }, getValue());
629 | Assert.same({ acc:165, v:7 }, getValue());
630 | Assert.same({ op:"OpAdd", acc:5, v:8 }, getValue());
631 | Assert.isFalse(t.hasNext());
632 | }
633 |
634 | public function test_try()
635 | {
636 | var throwobj:Dynamic = null,
637 | i = 0;
638 | function mayThrow()
639 | {
640 | if (throwobj != null)
641 | {
642 | var t = throwobj;
643 | throwobj = null;
644 | throw t;
645 | }
646 | return i++;
647 | }
648 |
649 | var t = test({
650 | while(true)
651 | {
652 | var acc = 100;
653 | try
654 | {
655 | acc+= 10;
656 | @yield { v:0, retn:"A", acc:acc };
657 | try
658 | {
659 | acc += 2;
660 | if (mayThrow() == 0)
661 | {
662 | acc -= 4;
663 | @yield { v:mayThrow(), retn:"B", acc:acc };
664 | acc += 6;
665 | @yield { v:mayThrow(), retn:"-", acc:acc };
666 | acc -= 100;
667 | } else {
668 | acc += 300;
669 | @yield { v:mayThrow(), retn:"AB", acc:acc };
670 | @yield { v:mayThrow(), retn:"-", acc:acc };
671 | acc -= 500;
672 | }
673 | }
674 | catch(e:String)
675 | {
676 | @yield { v:mayThrow(), retn:"String " + e, acc:++acc };
677 | acc = 5;
678 | @yield { v:mayThrow(), retn:"String", acc:++acc };
679 | acc += 4;
680 | try
681 | {
682 | @yield { v:mayThrow(), retn:"String", acc:++acc };
683 | acc += 15;
684 | @yield { v:mayThrow(), retn:"StringT2", acc:acc };
685 | acc += 5;
686 | @yield { v:mayThrow(), retn:"-", acc:acc };
687 | }
688 | catch(e:Dynamic)
689 | {
690 | @yield true;
691 | try
692 | {
693 | @yield { v:mayThrow(), retn:"StringT3", acc:acc };
694 | acc += 20;
695 | @yield { v:mayThrow(), retn:"-", acc:acc };
696 | }
697 | catch(str:String)
698 | {
699 | @yield { v:mayThrow(), retn:"-", acc:acc };
700 | }
701 | }
702 | }
703 | catch(e:haxe.io.Eof)
704 | {
705 | @yield { v:mayThrow(), retn:"-", acc:acc };
706 | }
707 | }
708 | catch(e:haxe.io.Eof)
709 | {
710 | @yield { v:mayThrow(), retn:"eof", acc:acc };
711 | }
712 | }
713 | });
714 |
715 | inline function getValue() return t.hasNext() ? t.next() : null;
716 | Assert.same({ v:0, retn:"A", acc:110 }, getValue());
717 | Assert.same({ v:1, retn:"B", acc:108 }, getValue());
718 |
719 | throwobj = "SomeString";
720 | Assert.same({ v:2, retn:"String SomeString", acc:115 }, getValue());
721 | Assert.same({ v:3, retn:"String", acc:6 }, getValue());
722 | Assert.same({ v:4, retn:"String", acc:11 }, getValue());
723 | Assert.same({ v:5, retn:"StringT2", acc:26 }, getValue());
724 |
725 | throwobj = new haxe.io.Eof();
726 | Assert.equals(true,getValue());
727 | Assert.same({ v:6, retn:"StringT3", acc:31 }, getValue());
728 | throwobj = new haxe.io.Eof();
729 | Assert.same({ v:7, retn:"eof", acc:51 }, getValue());
730 |
731 | Assert.same({ v:0, retn:"A", acc:110 }, getValue());
732 | Assert.same({ v:9, retn:"AB", acc:412 }, getValue());
733 | throwobj = "OtherString";
734 | Assert.same({ v:10, retn:"String OtherString", acc:413 }, getValue());
735 | throwobj = "AnotherString";
736 | var hadExc = false;
737 | try {
738 | getValue();
739 | } catch(e:String) {
740 | hadExc = true;
741 | Assert.equals("AnotherString",e);
742 | }
743 | Assert.isTrue(hadExc);
744 | Assert.isFalse(t.hasNext());
745 | }
746 |
747 | //test private access
748 | //test 'this'
749 | private function test_pvt_access()
750 | {
751 | var t = test({
752 | //this value get
753 | var theValue = someTest;
754 | @yield { v:1, val:theValue };
755 | Assert.equals('someTest', theValue);
756 | //this function call
757 | @yield { v:2, val:pvtFunc() };
758 | @yield { v:3, val:theValue != someTest };
759 | @yield { v:4, val:someTest };
760 | });
761 |
762 | inline function getValue() return t.hasNext() ? t.next() : null;
763 | Assert.same({ v:1, val:'someTest'}, getValue());
764 | Assert.same({ v:2, val:true}, getValue());
765 | Assert.same({ v:3, val:true}, getValue());
766 | Assert.same({ v:4, val:'didCall'}, getValue());
767 | Assert.isFalse(t.hasNext());
768 | }
769 |
770 | private function pvtFunc()
771 | {
772 | this.someTest = "didCall";
773 | return true;
774 | }
775 |
776 |
777 | //test type parameter
778 | private function localTypeParam(v:T, y:T)
779 | {
780 | return test({
781 | @yield v;
782 | @yield y;
783 | @yield v == y;
784 | });
785 | }
786 |
787 | public function test_tparam()
788 | {
789 | inline function getVal(t:Iterator) return t.hasNext() ? t.next() : null;
790 | var t1 = localTypeParam(10,20);
791 | Assert.equals(10,getVal(t1));
792 | Assert.equals(20,getVal(t1));
793 | Assert.equals(false,getVal(t1));
794 | Assert.isFalse(t1.hasNext());
795 |
796 | t1 = localTypeParam('a','a');
797 | Assert.equals('a',getVal(t1));
798 | Assert.equals('a',getVal(t1));
799 | Assert.equals(true,getVal(t1));
800 | Assert.isFalse(t1.hasNext());
801 |
802 | function fnTypeParam(a:Array)
803 | {
804 | return test({
805 | var last = null;
806 | for (v in a)
807 | {
808 | @yield v;
809 | @yield v == last;
810 | last = v;
811 | }
812 | });
813 | }
814 | t1 = fnTypeParam([1,2,1,1]);
815 | Assert.equals(1,getVal(t1));
816 | Assert.equals(false,getVal(t1));
817 | Assert.equals(2,getVal(t1));
818 | Assert.equals(false,getVal(t1));
819 | Assert.equals(1,getVal(t1));
820 | Assert.equals(false,getVal(t1));
821 | Assert.equals(1,getVal(t1));
822 | Assert.equals(true,getVal(t1));
823 | Assert.isFalse(t1.hasNext());
824 | }
825 |
826 | //better naming for defined classes
827 | public function test_naming()
828 | {
829 | var x = test({
830 | @yield 1;
831 | @yield 2;
832 | @yield 3;
833 | });
834 |
835 | Assert.isTrue(Type.getClassName(Type.getClass(x)).indexOf('test_naming') >= 0);
836 | }
837 |
838 | //TODO test v_captured fail - v_captured is only added later; see how to implement
839 | // public function test_captured()
840 | // {
841 | // var x = 10;
842 | // function testC()
843 | // {
844 | // return fails(test({
845 | // @yield x;
846 | // x = 20;
847 | // @yield x;
848 | // }));
849 | // }
850 | // Assert.isTrue(testC());
851 | // }
852 | #end
853 | }
854 |
--------------------------------------------------------------------------------
/unihx/_internal/Compiler.hx:
--------------------------------------------------------------------------------
1 | package unihx._internal;
2 | import haxe.macro.*;
3 | import sys.FileSystem.*;
4 | using StringTools;
5 |
6 | class Compiler
7 | {
8 | public static function compile():Void
9 | {
10 | var cwd = normalize(Sys.getCwd());
11 | var asm = '../Library/ScriptAssemblies';
12 | if (exists(asm))
13 | {
14 | for (file in readDirectory(asm))
15 | {
16 | if (file.endsWith('.dll'))
17 | haxe.macro.Compiler.addNativeLib('$asm/$file');
18 | }
19 | }
20 | // var files = [];
21 | var paths = [ for (p in Context.getClassPath()) if (normalize(p) != null) normalize(p) ];
22 | for (i in 0...paths.length)
23 | {
24 | var cp = paths[i];
25 | if (cp.startsWith(cwd))
26 | {
27 | collect(paths,i);
28 | }
29 | }
30 | haxe.macro.Compiler.include('unihx._internal.editor');
31 | }
32 |
33 | private static function normalize(path:String)
34 | {
35 | if (path == "")
36 | path = ".";
37 | if (!exists(path))
38 | return null;
39 | try
40 | {
41 | var ret = fullPath(haxe.io.Path.removeTrailingSlashes(path));
42 | switch (Sys.systemName())
43 | {
44 | case "Windows" | "Mac":
45 | ret = ret.toLowerCase();
46 | case _:
47 | }
48 | return ret;
49 | }
50 | catch(e:Dynamic)
51 | {
52 | return null;
53 | }
54 | }
55 |
56 | private static function collect(cps:Array, index:Int, ?pack)
57 | {
58 | var cp = cps[index];
59 | var slash = "/",
60 | dot = '.';
61 | if (pack == null)
62 | {
63 | slash = "";
64 | pack = [];
65 | dot = '';
66 | }
67 | var path = cp + slash + pack.join('/');
68 | for (file in readDirectory(path))
69 | {
70 | var path = path + "/" + file;
71 | if (isDirectory(path))
72 | {
73 | var p = normalize(path),
74 | found = false;
75 | for (j in 0...cps.length)
76 | {
77 | if (j != index && cps[j] == p)
78 | {
79 | found = true;
80 | break;
81 | }
82 | }
83 | if (!found)
84 | {
85 | pack.push(file);
86 | collect(cps,index,pack);
87 | pack.pop();
88 | }
89 | } else if (file.endsWith('.hx')) {
90 | Context.getModule(pack.join('.') + dot + file.substr(0,-3));
91 | }
92 | }
93 | }
94 |
95 | private static function getStdDir()
96 | {
97 | for (cp in Context.getClassPath())
98 | {
99 | var cp = haxe.io.Path.removeTrailingSlashes(cp);
100 | if (exists(cp) && !cp.endsWith('_std') && cp.endsWith('std'))
101 | {
102 | return cp;
103 | }
104 | }
105 | return null;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/unihx/_internal/PrivateAccessMacro.hx:
--------------------------------------------------------------------------------
1 | package unihx._internal;
2 | import haxe.macro.Expr;
3 | import haxe.macro.Context.*;
4 | import haxe.macro.Context;
5 | import haxe.macro.Type;
6 |
7 | using haxe.macro.ExprTools;
8 | using haxe.macro.TypeTools;
9 | using haxe.macro.TypedExprTools;
10 | using Lambda;
11 | using StringTools;
12 |
13 | class PrivateAccessMacro
14 | {
15 | #if macro
16 | public static function build():Type
17 | {
18 | switch (Context.getLocalType()) {
19 | case TInst(_, params):
20 | var module = getConst(params.shift(),1),
21 | typeName = getConst(params.shift(),2);
22 |
23 | var mod = getModule(module);
24 | for (m in mod) {
25 | switch(m) {
26 | case TInst(c,_):
27 | if (c.get().name == typeName)
28 | return TInst(c,params);
29 | case TEnum(c,_):
30 | if (c.get().name == typeName)
31 | return TEnum(c,params);
32 | case TType(c,_):
33 | if (c.get().name == typeName)
34 | return TType(c,params);
35 | case TAbstract(c,_):
36 | if (c.get().name == typeName)
37 | return TAbstract(c,params);
38 | case _:
39 | }
40 | }
41 | throw new Error('Private type "${typeName}" cannot be found on "$module"',currentPos());
42 | case _:
43 | throw "assert";
44 | }
45 | }
46 |
47 | private static function getConst(t:Type, n:Int):String
48 | {
49 | switch (t) {
50 | case TInst(x,_):
51 | var name = x.get().name;
52 | if (!name.startsWith('S'))
53 | throw new Error('PrivateTypeAccess must have the parameter number $n as a String', currentPos());
54 | return name.substr(1);
55 | case _:
56 | throw new Error('PrivateTypeAccess must have the parameter number $n as a String', currentPos());
57 | }
58 | }
59 | #end
60 | }
61 |
--------------------------------------------------------------------------------
/unihx/_internal/PrivateTypeAccess.hx:
--------------------------------------------------------------------------------
1 | package unihx._internal;
2 |
3 | @:genericBuild(unihx._internal.PrivateAccessMacro.build())
4 | class PrivateTypeAccess {}
5 |
--------------------------------------------------------------------------------
/unihx/_internal/StructHelper.hx:
--------------------------------------------------------------------------------
1 | package unihx._internal;
2 | import haxe.macro.Expr;
3 |
4 | class StructHelper
5 | {
6 | public static function with(fields:Array, clsName:ComplexType, ethis:Expr, expr:Expr):Expr
7 | {
8 | switch (expr.expr)
9 | {
10 | case EObjectDecl(declFieldsArr):
11 | var declFields = new Map();
12 | {
13 | for (f in declFieldsArr)
14 | {
15 | if (declFields.exists(f.field))
16 | throw new Error('Duplicate field definition: ${f.field}', f.expr.pos);
17 | else if (fields.indexOf(f.field) == -1)
18 | throw new Error('Extra field constructor: ${f.field}', f.expr.pos);
19 | declFields[f.field] = f.expr;
20 | }
21 | }
22 | var ctorArgs = fields.map(function(f) {
23 | if (declFields.exists(f))
24 | {
25 | return declFields[f];
26 | } else {
27 | return macro @:pos(expr.pos) $ethis.$f;
28 | }
29 | });
30 | var type = switch (clsName)
31 | {
32 | case TPath(p):
33 | p;
34 | case _:
35 | throw 'assert';
36 | }
37 |
38 | return { expr:ENew(type, ctorArgs), pos:expr.pos };
39 | case _:
40 | throw new Error("The `with' macro expects an anonymous object declaration as its argument", expr.pos);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/unihx/_internal/Yield.hx:
--------------------------------------------------------------------------------
1 | package unihx._internal;
2 |
3 | class Yield
4 | {
5 | macro public static function getIterator(e:haxe.macro.Expr):haxe.macro.Expr
6 | {
7 | return YieldGenerator.getIterator(e);
8 | }
9 |
10 | // only typing helper
11 | private static function __yield__(t:T):T
12 | {
13 | return t;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/unihx/_internal/YieldBase.hx:
--------------------------------------------------------------------------------
1 | package unihx._internal;
2 |
3 | class YieldBase #if !macro implements cs.system.collections.IEnumerator #end
4 | {
5 | @:property public var Current(get,never):Dynamic;
6 | private var eip:Int = 0;
7 | private var value:Dynamic;
8 | private var exc:Dynamic;
9 |
10 | public function MoveNext():Bool
11 | {
12 | return false;
13 | }
14 |
15 | inline public function get_Current():Dynamic
16 | {
17 | return value;
18 | }
19 |
20 | inline public function hasNext():Bool
21 | {
22 | return MoveNext();
23 | }
24 |
25 | inline public function next():Dynamic
26 | {
27 | return value;
28 | }
29 |
30 | /**
31 | This function will be called internally by the handler to see if an exception
32 | can be handled. It will work like a MoveNext() call.
33 |
34 | If the handler returns false, the enumerator will be in a 'errored' state and will not return any more values
35 | **/
36 | public function handleError(exc:Dynamic):Bool
37 | {
38 | this.eip = -1; //error state
39 | return false;
40 | }
41 |
42 | public function Reset():Void
43 | {
44 | this.eip = 0;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/unihx/_internal/YieldGenerator.hx:
--------------------------------------------------------------------------------
1 | package unihx._internal;
2 | import haxe.macro.Expr;
3 | import haxe.macro.Context.*;
4 | import haxe.macro.Context;
5 | import haxe.macro.Type;
6 |
7 | using haxe.macro.ExprTools;
8 | using haxe.macro.TypeTools;
9 | using haxe.macro.TypedExprTools;
10 | using haxe.macro.ComplexTypeTools;
11 | using Lambda;
12 | using StringTools;
13 |
14 | class YieldGenerator
15 | {
16 | static var packs = new Map();
17 | var expr:TypedExpr;
18 | var usedVars:Map>;
19 |
20 | // control flow graph
21 | var id = -1;
22 | var cfgs:Array;
23 | var current:FlowGraph;
24 |
25 | var tbool:Type;
26 | var tint:Type;
27 | var tdynamic:Type;
28 |
29 | var goto:TypedExpr;
30 | var gotoEnd:TypedExpr;
31 | var exc:TypedExpr;
32 | var pos:Position;
33 |
34 | var pack:String;
35 | var condGraph:Null;
36 |
37 | var onBreak:TypedExpr;
38 | var onContinue:TypedExpr;
39 | var catchStack:Array>;
40 | var bakedCatchStack:Array<{ t:Type, gotoHandler:TypedExpr }>;
41 |
42 | var rethrow:Expr;
43 |
44 | var thisUsed:Bool = false;
45 | var infos:haxe.PosInfos;
46 |
47 | public function new(pack:String, e:Expr)
48 | {
49 | var expr = typeExpr(macro { var __yield__:Dynamic = null; ${prepare(e)}; });
50 | switch(expr.expr)
51 | {
52 | case TBlock(bl):
53 | this.expr = bl[1];
54 | default: throw "assert";
55 | }
56 |
57 | this.catchStack = [];
58 | this.usedVars = new Map();
59 | this.cfgs = [];
60 | newFlow();
61 | this.current = cfgs[0];
62 |
63 | this.tbool = getType("Bool");
64 | this.tint = getType("Int");
65 | this.tdynamic = getType("Dynamic");
66 |
67 | this.goto = typeExpr( macro untyped __goto__ );
68 | this.gotoEnd = typeExpr( macro untyped __goto_end__ );
69 | this.exc = typeExpr( macro untyped __exc__ );
70 | this.pos = currentPos();
71 |
72 | this.pack = pack;
73 | this.rethrow = if (defined('cs'))
74 | macro cs.Lib.rethrow(exc);
75 | else if (defined('neko'))
76 | macro neko.Lib.rethrow(exc);
77 | else if (defined('cpp'))
78 | macro cpp.Lib.rethrow(exc);
79 | else if (defined('php'))
80 | macro php.Lib.rethrow(exc);
81 | else
82 | macro throw exc;
83 |
84 | this.infos = getHere(e.pos);
85 | // trace(infos);
86 | }
87 |
88 | static function extractYield(e:Expr):Null
89 | {
90 | var hasYield = false;
91 | function map(e:Expr)
92 | {
93 | return switch(e.expr) {
94 | case EBinop(op,e1,e2):
95 | { expr:EBinop(op, map(e1), e2), pos:e.pos };
96 | case EUnop(op,post,e1):
97 | { expr:EUnop(op,post,map(e1)), pos:e.pos };
98 | case EMeta({ name:'yield' }, e):
99 | hasYield = true;
100 | e;
101 | case _:
102 | e;
103 | }
104 | }
105 | var ret = map(e);
106 | if (hasYield)
107 | return ret;
108 | else
109 | return null;
110 | }
111 |
112 | static function prepare(e:Expr):Expr
113 | {
114 | return switch(e) {
115 | case macro __yield__:
116 | throw new Error("Reserved variable name: __yield__", e.pos);
117 | case macro @yield $something:
118 | return macro __yield__(${prepare(something)});
119 | case { expr:EBinop(op,e1,e2) }:
120 | var ret = extractYield(e);
121 | if (ret == null)
122 | e.map(prepare);
123 | else
124 | macro __yield__(${prepare( prepare(ret) )});
125 | case _:
126 | return e.map(prepare);
127 | }
128 | }
129 |
130 | public static function make(pack,e:Expr):Expr
131 | {
132 | return new YieldGenerator(pack,e).change();
133 | }
134 |
135 | public static function getIterator(e:Expr):Expr
136 | {
137 | var t = typeof(e);
138 | switch (t.follow())
139 | {
140 | case TAnonymous(a):
141 | if (a.get().fields.exists(function(cf) return cf.name == "hasNext" || cf.name == "next"))
142 | return e;
143 | else
144 | return macro $e.iterator();
145 | case TInst(t,_):
146 | if (t.get().findField('iterator') != null)
147 | return macro $e.iterator();
148 | else
149 | return e;
150 | case _:
151 | throw new Error('This expression has type $t, but an Iterable or Iterator was expected', e.pos);
152 | }
153 | }
154 |
155 | private function bakeCatches()
156 | {
157 | var i = catchStack.length,
158 | stack = catchStack;
159 | var baked = this.bakedCatchStack = [];
160 | while (i --> 0)
161 | {
162 | var cur = stack[i];
163 | for (cur in cur)
164 | {
165 | var t = cur.t;
166 | var add = true;
167 | for (v in baked)
168 | {
169 | if (t.unify(v.t))
170 | {
171 | add = false;
172 | break;
173 | }
174 | }
175 | if (add)
176 | baked.push(cur);
177 | }
178 | }
179 | }
180 |
181 | inline function newFlow()
182 | {
183 | var ret = { block:[], tryctx:bakedCatchStack, id: ++id, next: null };
184 | cfgs.push(ret);
185 | current = ret;
186 | }
187 |
188 | inline function setUsed(id:Int)
189 | {
190 | var ret =usedVars[id];
191 | if (ret == null)
192 | {
193 | usedVars[id] = ret = new Map();
194 | }
195 | ret[current] = current;
196 | }
197 |
198 | function ensureNoYield(e:TypedExpr)
199 | {
200 | switch (e.expr)
201 | {
202 | case TCall( { expr:TLocal({ name:"__yield__" }) }, [e]):
203 | throw new Error('@yield cannot be used here', e.pos);
204 | case TLocal(v) | TVar(v,_):
205 | setUsed(v.id);
206 | e.iter(ensureNoYield);
207 | case TReturn(_):
208 | throw new Error("Cannot return inside a 'yield' context", e.pos);
209 | case _:
210 | e.iter(ensureNoYield);
211 | }
212 | }
213 |
214 | function hasYield(e:TypedExpr)
215 | {
216 | var has = false;
217 | function iter(e:TypedExpr)
218 | {
219 | switch (e.expr)
220 | {
221 | case TCall( { expr:TLocal({ name:"__yield__" }) }, [e]):
222 | has = true;
223 | case _:
224 | if (!has) e.iter(iter);
225 | }
226 | }
227 | iter(e);
228 | return has;
229 | }
230 |
231 | inline function mkGetExc(t:Type):TypedExpr
232 | {
233 | return { expr:TCast(exc, null), t:t, pos:pos };
234 | }
235 |
236 | function mkGoto(id:Int,final:Bool):TypedExpr
237 | {
238 | return { expr: TCall(goto, [{ expr:TConst(TInt(id)), t:tint, pos:pos }, { expr:TConst(TBool(final)), t:tbool, pos:pos }]), t:tdynamic, pos:pos };
239 | }
240 |
241 | function mkGotoEnd(id:Int,final:Bool):TypedExpr
242 | {
243 | return { expr: TCall(gotoEnd, [{ expr:TConst(TInt(id)), t:tint, pos:pos }, { expr:TConst(TBool(final)), t:tbool, pos:pos }]), t:tdynamic, pos:pos };
244 | }
245 |
246 | function mkNothing():TypedExpr
247 | {
248 | return { expr: TBlock([]), t:tdynamic, pos:pos };
249 | }
250 |
251 | static function replace(from:TypedExpr, to:TypedExpr):Void
252 | {
253 | from.expr = to.expr;
254 | from.t = to.t;
255 | from.pos = to.pos;
256 | }
257 |
258 | function iter(e:TypedExpr)
259 | {
260 | switch(e.expr)
261 | {
262 | case TVar(v,_) | TLocal(v):
263 | setUsed(v.id);
264 | current.block.push(e);
265 | case TFunction(f):
266 | ensureNoYield(e);
267 | current.block.push(e);
268 | case TBlock(el):
269 | for (e in el)
270 | iter(e);
271 | case TIf(econd,eif,eelse):
272 | ensureNoYield(econd);
273 | var yieldIf = hasYield(eif),
274 | yieldElse = eelse != null && hasYield(eelse);
275 | if (yieldIf || yieldElse)
276 | {
277 | // invert if and else - if necessary
278 | if (yieldIf && !yieldElse && eelse != null)
279 | {
280 | econd = mk_not(econd);
281 | var tmp = eelse;
282 | eelse = eif;
283 | eif = tmp;
284 |
285 | yieldIf = false;
286 | yieldElse = true;
287 | }
288 | // if (!cond) goto else;
289 | var gotoElse = mkNothing();
290 | current.block.push({ expr: TIf(mk_not(econd),gotoElse,null), t: tdynamic, pos: econd.pos });
291 |
292 | // otherwise continue on eif
293 | iter(eif);
294 | var endIfBlock = current;
295 | // starting else
296 | newFlow();
297 | replace(gotoElse, mkGoto(current.id, true));
298 |
299 | // make else block
300 | if (eelse != null)
301 | {
302 | iter(eelse);
303 | }
304 | newFlow();
305 |
306 | endIfBlock.next = current.id;
307 | } else {
308 | ensureNoYield(eif);
309 | if (eelse != null)
310 | ensureNoYield(eelse);
311 | current.block.push(e);
312 | }
313 |
314 | case TWhile(econd, block, normalWhile) if(hasYield(block)):
315 | ensureNoYield(econd);
316 |
317 | var prelude = null;
318 | if (!normalWhile)
319 | {
320 | newFlow();
321 | prelude = current;
322 | }
323 | newFlow();
324 | var lastOnBreak = onBreak,
325 | lastOnContinue = onContinue;
326 | onBreak = mkNothing();
327 | onContinue = mkNothing();
328 |
329 | // while condition
330 | var condCfg = current;
331 | var changedCond = { expr: TIf( mk_not(econd), onBreak, null ), t: tdynamic, pos:econd.pos };
332 | iter(changedCond);
333 |
334 | //body
335 | newFlow();
336 | var bodyCfg = current;
337 | if (prelude != null)
338 | prelude.next = bodyCfg.id;
339 | iter(block);
340 | current.next = condCfg.id;
341 | newFlow();
342 |
343 | //returning last loop
344 | replace(onBreak,mkGoto(current.id,true));
345 | replace(onContinue,mkGoto(condCfg.id,true));
346 | this.onBreak = lastOnBreak;
347 | this.onContinue = lastOnContinue;
348 |
349 | case TBreak:
350 | if (this.onBreak == null) throw new Error("Break outside loop",e.pos);
351 | current.block.push(onBreak);
352 | case TContinue:
353 | if (this.onContinue == null) throw new Error("Continue outside loop",e.pos);
354 | current.block.push(onContinue);
355 |
356 | case TSwitch(econd,ecases,edef):
357 | var cur = current,
358 | curBlock = cur.block,
359 | curNext = cur.next;
360 | ensureNoYield(econd);
361 | var currents = [cur];
362 | for (c in ecases)
363 | {
364 | current = cur;
365 | var bl = cur.block = [];
366 | cur.next = id + 1;
367 | for (v in c.values) ensureNoYield(v);
368 | iter(c.expr);
369 | c.expr = mk_block(bl);
370 | currents.push(current);
371 | }
372 | if (edef != null)
373 | {
374 | current = cur;
375 | var defs = cur.block = [];
376 | cur.next = id + 1;
377 | iter(edef);
378 | edef = mk_block(defs);
379 | currents.push(current);
380 | }
381 | current = cfgs[cfgs.length-1];
382 |
383 | cur.next = curNext;
384 | cur.block = curBlock;
385 | curBlock.push({ expr:TSwitch(econd, ecases, edef), t:e.t, pos:e.pos });
386 | if (cur != current)
387 | {
388 | newFlow();
389 | for (c in currents)
390 | c.next = current.id;
391 | }
392 | case TTry(etry, ecatches):
393 | var cur = current,
394 | curNext = cur.next,
395 | curBlock = cur.block;
396 | var currents = [];
397 |
398 | if (hasYield(etry))
399 | {
400 | var handlers = [ for (c in ecatches) { t:c.v.t, gotoHandler: mkNothing() } ];
401 | this.catchStack.push(handlers);
402 | var old = this.bakedCatchStack;
403 | bakeCatches();
404 | newFlow(); //we need a new flow since we'll change the handlers mask
405 |
406 | iter(etry);
407 | currents.push(current);
408 | this.catchStack.pop();
409 | this.bakedCatchStack = old;
410 | for (i in 0...ecatches.length)
411 | {
412 | var c = ecatches[i],
413 | handler = handlers[i];
414 | newFlow();
415 | replace(handler.gotoHandler, mkGoto(current.id, true));
416 | iter({ expr: TVar(c.v, mkGetExc(c.v.t)), t:tdynamic, pos:c.expr.pos });
417 | iter(c.expr);
418 | currents.push(current);
419 | }
420 | } else {
421 | var tryblock = cur.block = [];
422 | iter(etry);
423 | var newc = [];
424 | for (c in ecatches)
425 | {
426 | current = cur;
427 | cur.next = id + 1;
428 | var bl = cur.block = [];
429 | var newVar = alloc_var(c.v.name, c.v.t);
430 | iter({ expr: TVar(c.v, { expr: TLocal(newVar), t:newVar.t, pos:c.expr.pos }), t:tdynamic, pos:c.expr.pos });
431 | iter(c.expr);
432 | newc.push({ v: newVar, expr:mk_block(bl) });
433 | currents.push(current);
434 | }
435 | cur.block = curBlock;
436 | curBlock.push({ expr:TTry(mk_block(tryblock), newc), t: e.t, pos:e.pos });
437 | cur.next = curNext;
438 | }
439 | if (cur != current)
440 | {
441 | newFlow();
442 | for (c in currents)
443 | c.next = current.id;
444 | }
445 |
446 | case TMeta(meta,e1):
447 | iter(e1);
448 |
449 | case TFor(v,eit,eblock):
450 | if (hasYield(eblock))
451 | {
452 | switch (typeExpr( macro var _iterator_ ).expr) {
453 | case TVar(v2,_):
454 | v2.t = eit.t;
455 | iter({ expr:TVar(v2,eit), t:tdynamic, pos:eit.pos });
456 | var local = { expr:TLocal(v2), t:eit.t, pos:eit.pos };
457 |
458 | var wexpr = {
459 | expr:TWhile(
460 | { expr:TCall( mk_field(local, 'hasNext', tdynamic), []), t:tbool, pos:eit.pos },
461 | { expr:TBlock([{ expr:TVar(v, { expr:TCall( mk_field(local, 'next', tdynamic), []), t:v.t, pos:eit.pos }), t:tdynamic, pos:eit.pos }, eblock]), t:tdynamic, pos:eblock.pos },
462 | true),
463 | t: tdynamic,
464 | pos: e.pos };
465 | iter(wexpr);
466 | case _: throw 'assert';
467 | }
468 | } else {
469 | ensureNoYield(e);
470 | current.block.push(e);
471 | }
472 |
473 | case TCall( { expr:TLocal({ name:"__yield__" }) }, [ev]):
474 | // return value
475 | ensureNoYield(ev);
476 | current.block.push( { expr:TMeta({name:"yield", params:[], pos:ev.pos}, ev), t: ev.t, pos:ev.pos } );
477 | // current.block.push( mk_assign( mk_this('value', ev.t, e.pos), ev, e.pos) );
478 | if (current.next != null)
479 | current.block.push( mkGoto( current.next, false ) );
480 | else
481 | current.block.push( mkGotoEnd( current.id, false ) );
482 | // set to next
483 | current.block.push( { expr: TReturn( { expr:TConst(TBool(true)), t:tbool, pos:e.pos } ), t:tbool, pos:e.pos } );
484 | // break flow
485 | newFlow();
486 | case TReturn(_):
487 | throw new Error("Cannot return inside a 'yield' context", e.pos);
488 |
489 | case _:
490 | ensureNoYield(e);
491 | current.block.push(e);
492 | }
493 | }
494 |
495 | public function change():Expr
496 | {
497 | // create the control flow graph
498 | iter(expr);
499 | var used = new Map();
500 | {
501 | // get used vars - canonically
502 | for (k in usedVars.keys())
503 | {
504 | var cur = new Map();
505 | used[k] = cur;
506 | for (cfg in usedVars[k])
507 | {
508 | var cfg = cfg;
509 | cur[cfg.id] = true;
510 | }
511 | }
512 | }
513 | // get the variables that need to be changed
514 | var changed = new Map(),
515 | used = [ for (k in used.keys()) k => this.usedVars.get(k).count() ];
516 | var external = [ for (ext in getLocalTVars()) ext.id => ext ];
517 | for (ext in external)
518 | used[ext.id] = 2; //mark as used
519 | // trace(changed,used);
520 | // create cases function
521 | var ecases = [],
522 | acc = [];
523 | for (cfg in cfgs)
524 | {
525 | acc.push({ expr:EConst(CInt(cfg.id + "")), pos:pos });
526 | if (cfg.block.length == 0 && cfg.next == null)
527 | continue;
528 | //TODO tryctx
529 | var expr = getExprFromCg(cfg, used, changed);
530 | ecases.push({ values:acc, expr: expr });
531 | acc = [];
532 | }
533 | var eswitch = { expr:ESwitch(macro this.eip, ecases, macro return false), pos:pos };
534 |
535 | eswitch = macro try { @:privateAccess $eswitch; } catch(exc:Dynamic) { if (!this.handleError(exc)) {$rethrow; return false;} };
536 | // see if C#
537 | if (!false)
538 | {
539 | eswitch = macro while(true) $eswitch;
540 | }
541 | // trace(eswitch.toString());
542 |
543 | var extChanged = [ for (ext in external) if (changed.exists(ext.id)) ext ];
544 | if (thisUsed)
545 | {
546 | var ethis = { id:-1, name:'this', t: typeof(macro this), capture:false, extra:null };
547 | extChanged.push(ethis);
548 | changed[ethis.id] = ethis;
549 | }
550 |
551 | var tparams = new Map();
552 | for (c in extChanged)
553 | collectTParams(c.t, tparams);
554 |
555 | //create new() function
556 | var nf = {
557 | name: "new",
558 | kind: FFun({
559 | args: [ for (arg in extChanged) { name: getVarName(arg), type: null } ],
560 | ret: null,
561 | expr: { expr:EBlock([ for (arg in extChanged) { var name = getVarName(arg); macro this.$name = $i{name}; } ]), pos:pos }
562 | }),
563 | pos: pos
564 | };
565 |
566 | //create all changed fields
567 | var clsnum = packs.get(pack);
568 | if (clsnum == null)
569 | {
570 | clsnum = 0;
571 | }
572 | packs[pack] = clsnum + 1;
573 | var pack = pack.split('.'),
574 | name = "yield_" + (infos != null ? infos.className.split('.').pop() + "_" + infos.methodName + "_" + infos.lineNumber + "_": "" + clsnum);
575 |
576 | var cls = macro class extends unihx._internal.YieldBase {
577 | override public function MoveNext():Bool
578 | $eswitch;
579 | };
580 | cls.fields.push(nf);
581 | var excHandler = getExcHandler();
582 | if (excHandler != null)
583 | cls.fields.push(excHandler);
584 | var pvtAcc = macro : unihx._internal.PrivateTypeAccess;
585 | for (changed in changed)
586 | {
587 | var t2 = toComplexType(changed.t);
588 | // trace(changed.name, changed.t.toString(), t2.toString());
589 | cls.fields.push({
590 | name:getVarName(changed),
591 | kind: FVar(t2,null),
592 | pos: pos
593 | });
594 | }
595 | cls.params = [ for (k in tparams.keys()) { name:k } ];
596 | cls.name = name;
597 | cls.pack = pack;
598 | defineType(cls);
599 | return { expr:ENew({ pack:pack, name: name }, [ for (arg in extChanged) macro $i{arg.name} ]), pos:pos };
600 | }
601 |
602 | function getExcHandler()
603 | {
604 | var all = new Map();
605 | var found = false;
606 | for (i in 0...cfgs.length)
607 | {
608 | var cfg = cfgs[i];
609 | if (cfg.tryctx != null)
610 | {
611 | found =true;
612 | var g = all[cfg.tryctx];
613 | if (g == null)
614 | {
615 | all[cfg.tryctx] = g = { ctx:cfg.tryctx, ids:[] };
616 | }
617 | g.ids.push(cfg.id);
618 | }
619 | }
620 |
621 | if (!found)
622 | return null;
623 | var used = new Map(),
624 | changed = new Map();
625 | var cases = [];
626 | for (ctx in all)
627 | {
628 | var ids = ctx.ids,
629 | ctx = ctx.ctx;
630 | var exprs = [];
631 | for (c in ctx)
632 | {
633 | var module = switch(c.t) {
634 | case TInst(c,_):
635 | exprModule(TClassDecl(c),pos);
636 | case TEnum(e,_):
637 | exprModule(TEnumDecl(e),pos);
638 | case TAbstract(a,_):
639 | exprModule(ModuleType.TAbstract(a),pos);
640 | case TType(t,_):
641 | exprModule(TTypeDecl(t),pos);
642 | case TDynamic(_):
643 | macro Dynamic;
644 | case _: throw 'assert: ' + c.t;
645 | };
646 | var gotoHandler = switch (c.gotoHandler.expr) {
647 | case TCall({ expr:TLocal({ name: "__goto__" }) }, [{ expr:TConst(TInt(i)) }, _]):
648 | macro { this.eip = $v{i}; return true; }
649 | case _:
650 | throw 'assert';
651 | };
652 | exprs.push(macro if(std.Std.is(exc,$module)) $gotoHandler);
653 | }
654 |
655 | cases.push({ values: [ for (v in ids) macro $v{v} ], expr: { expr:EBlock(exprs), pos:pos } });
656 | }
657 | var eswitch = { expr: ESwitch(macro this.eip, cases, null), pos:pos };
658 | var field = (macro class {
659 | override public function handleError(exc:Dynamic):Bool {
660 | this.exc = exc;
661 | $eswitch;
662 | this.eip = -1;
663 | this.exc = null;
664 | return false;
665 | }
666 | }).fields[0];
667 | return field;
668 | }
669 |
670 | function getExprFromCg(cfg:FlowGraph, used:Map, changed:Map):Expr
671 | {
672 | var exprs = [ for (e in cfg.block) texprToExpr(e,used,changed) ];
673 | if (exprs.length == 0)
674 | {
675 | exprs = [texprToExpr(mkGotoEnd(cfg.id,true),used,changed)];
676 | } else switch (exprs[exprs.length-1]) {
677 | case macro return $_:
678 | case macro this.eip = $_:
679 | case macro continue:
680 | case _:
681 | exprs.push(texprToExpr(mkGotoEnd(cfg.id, true),used,changed));
682 | }
683 | return { expr: EBlock(exprs), pos: pos };
684 | }
685 |
686 | function mk_assign(e1:TypedExpr, e2:TypedExpr, pos:Position):TypedExpr
687 | {
688 | return { expr: TBinop(OpAssign, e1, e2), t: e1.t, pos:pos };
689 | }
690 |
691 | function mk_field(e:TypedExpr, field:String, type:Type):TypedExpr
692 | {
693 | return { expr: TField(e, FDynamic(field)), t:type, pos:e.pos };
694 | }
695 |
696 | function mk_this(name:String, t:Type, pos:Position):TypedExpr
697 | {
698 | return { expr: TField({ expr:TConst(TThis), t:tdynamic, pos:pos }, FDynamic(name)), t: t, pos:pos };
699 | }
700 |
701 | static function mk_paren(e:TypedExpr):TypedExpr
702 | {
703 | return { expr: TParenthesis(e), t: e.t, pos: e.pos };
704 | }
705 |
706 | function mk_not(e:TypedExpr):TypedExpr
707 | {
708 | return switch(e.expr) {
709 | case TUnop(OpNot, false, e):
710 | e;
711 | case _:
712 | { expr: TUnop(OpNot, false, mk_paren(e)), t: tbool, pos: e.pos };
713 | }
714 | }
715 |
716 | function mk_block(el:Array):TypedExpr
717 | {
718 | return { expr: TBlock(el), t: tdynamic, pos: el.length > 0 ? el[0].pos : pos };
719 | }
720 |
721 | static function getHere(pos:Position)
722 | {
723 | var expr = typeExpr(macro @:pos(pos) {
724 | inline function here(?infos:haxe.PosInfos) return infos;
725 | here();
726 | });
727 | var ret:haxe.PosInfos = null;
728 | function getConst(e:TypedExpr):Dynamic {
729 | return switch(e.expr) {
730 | case TConst(TInt(i)): i;
731 | case TConst(TString(s)): s;
732 | case _: null;
733 | }
734 | }
735 | function iter(e:TypedExpr)
736 | {
737 | switch(e.expr) {
738 | case TObjectDecl(d):
739 | ret = cast {};
740 | for (arg in d)
741 | {
742 | Reflect.setField(ret,arg.name, getConst(arg.expr));
743 | }
744 | case _:
745 | e.iter(iter);
746 | }
747 | }
748 | iter(expr);
749 | return ret;
750 | }
751 |
752 | function alloc_var(name:String, t:Type):TVar
753 | {
754 | switch (typeExpr(macro var _).expr) {
755 | case TVar(v,_):
756 | v.name = name;
757 | v.t = t;
758 | return v;
759 | case _: throw 'assert';
760 | }
761 | }
762 |
763 | var inswitch = false;
764 | private function texprToExpr(e:TypedExpr, used:Map, changed:Map):Expr
765 | {
766 | function map(e:TypedExpr):Expr
767 | {
768 | return switch(e.expr) {
769 | case TConst(TThis):
770 | thisUsed = true;
771 | return macro this.parent;
772 | case TMeta({name:"yield"}, v):
773 | return macro this.value = ${ map(v) };
774 | case TLocal({ name:"__exc__" }):
775 | return macro this.exc;
776 | case TLocal(v) if (v.capture):
777 | throw new Error('Cannot bind to captured variable ${v.name}',e.pos);
778 | case TLocal(v) if (used.get(v.id) > 1):
779 | changed[v.id] = v;
780 | var name = getVarName(v);
781 | macro @:pos(e.pos) this.$name;
782 | case TVar(v,eset) if (used.get(v.id) > 1):
783 | changed[v.id] = v;
784 | var name = getVarName(v);
785 | if (eset == null)
786 | macro @:pos(e.pos) this.$name = null;
787 | else
788 | macro @:pos(e.pos) this.$name = ${map(eset)};
789 | case TNew(c, params, el):
790 | var complex = switch(toComplexType( TInst(c,params) )) {
791 | case TPath(p):
792 | p;
793 | case _:
794 | throw 'assert';
795 | };
796 | { expr: ENew( complex, [ for (e in el) map(e) ]), pos: e.pos };
797 | case TTypeExpr(m):
798 | return exprModule(m, e.pos);
799 |
800 | case TCall({ expr:TLocal({ name: "__goto__" }) }, [{expr:TConst(TInt(i))}, final]):
801 | var i = followId(i);
802 | switch (final.expr)
803 | {
804 | case TConst(TBool(true)) if (!inswitch && defined('cs')):
805 | var str = 'goto case $i';
806 | if (i > getMaxId())
807 | str = 'goto default';
808 | macro @:pos(e.pos) untyped __cs__($v{str});
809 | case TConst(TBool(true)):
810 | macro @:pos(e.pos) { this.eip = $v{i}; continue; };
811 |
812 | case TConst(TBool(false)):
813 | macro @:pos(e.pos) this.eip = $v{i};
814 | case _: throw new Error("Invalid goto expr", e.pos);
815 | }
816 | case TCall({ expr:TLocal({ name: "__goto_end__" }) }, [i, final]):
817 | var block = switch (i.expr) {
818 | case TConst(TInt(i)):
819 | cfgs[i];
820 | case _: throw "assert";
821 | };
822 | var i = if (block.next == null) block.id + 1; else block.next;
823 | i = followId(i);
824 | switch(final.expr)
825 | {
826 | case TConst(TBool(true)) if (!inswitch && defined('cs')):
827 | var str = 'goto case $i';
828 | if (i > getMaxId())
829 | str = 'goto default';
830 | macro @:pos(e.pos) untyped __cs__($v{str});
831 | case TConst(TBool(true)):
832 | macro @:pos(e.pos) { this.eip = $v{i}; continue; };
833 |
834 | case TConst(TBool(false)):
835 | macro @:pos(e.pos) this.eip = $v{i};
836 | case _: throw new Error("Invalid goto expr", e.pos);
837 | }
838 |
839 | // conversion boilerplate
840 | case TConst(_):
841 | getTypedExpr(e);
842 | case TMeta({ name:":ast", params: [p] }, _):
843 | p;
844 | case TEnumParameter(e1,ef,idx):
845 | var params = switch(ef.type.follow()) {
846 | case TFun(args,_):args;
847 | case _: throw 'assert';
848 | };
849 | var ecase = macro $i{ef.name},
850 | c2 = { expr: ECall(ecase,[ for (i in 0...params.length) if (i == idx) macro val; else macro _ ]), pos:e.pos };
851 | @:pos(e.pos) macro switch (${map(e1)}) { case $c2: val; default: throw 'assert'; };
852 | // these are considered complex, so the AST is handled in TMeta(Meta.Ast)
853 | // throw new Error('assert', e.pos);
854 | case TLocal(v):
855 | macro @:pos(e.pos) $i{v.name};
856 | case TBreak:
857 | macro @:pos(e.pos) break;
858 | case TContinue:
859 | macro @:pos(e.pos) continue;
860 | case TArray(e1,e2):
861 | macro @:pos(e.pos) ${map(e1)}[${map(e2)}];
862 | case TBinop(op,e1,e2):
863 | { expr: EBinop(op, map(e1), map(e2)), pos: e.pos };
864 | case TField(e1, fa):
865 | switch (fa) {
866 | case FInstance(_,cf) | FStatic(_,cf) | FAnon(cf) | FClosure(_,cf):
867 | var cf = cf.get();
868 | var field = { expr: EField(map(e1), cf.name), pos:e.pos };
869 | if (!cf.isPublic)
870 | macro @:pos(e.pos) $field;
871 | else
872 | field;
873 | case FDynamic(s):
874 | { expr: EField(map(e1), s), pos:e.pos };
875 | case FEnum(_,ef):
876 | { expr: EField(map(e1), ef.name), pos:e.pos };
877 | }
878 | case TParenthesis(e1):
879 | { expr: EParenthesis(map(e1)), pos: e.pos };
880 | case TObjectDecl(fields):
881 | { expr: EObjectDecl([ for (f in fields) { field:f.name, expr:map(f.expr) } ]), pos: e.pos };
882 | case TArrayDecl(el):
883 | { expr: EArrayDecl([ for (e in el) map(e) ]), pos: e.pos };
884 | case TCall(e1, el):
885 | { expr: ECall( map(e1), [ for ( e in el ) map(e) ] ), pos: e.pos };
886 | case TUnop(op,postFix,e1):
887 | { expr: EUnop(op, postFix, map(e1)), pos:e.pos };
888 | case TFunction(tf):
889 | { expr: EFunction(null, { args:[for (arg in tf.args) { name: arg.v.name, type:toComplexType(arg.v.t) }], ret:toComplexType(tf.t), expr:tf.expr == null ? null : map(tf.expr) }), pos:e.pos };
890 | case TVar(v, e1):
891 | { expr: EVars([{ name: v.name, type: toComplexType(v.t), expr: e1 == null ? null : map(e1) }]), pos: e.pos };
892 | case TBlock(el):
893 | { expr: EBlock([ for (e in el) map(e) ]), pos:e.pos };
894 | case TIf(econd,eif,eelse):
895 | { expr: EIf(map(econd), map(eif), eelse == null ? null : map(eelse)), pos: e.pos };
896 | case TReturn(e1):
897 | { expr: EReturn(map(e1)), pos: e.pos };
898 | case TThrow(e1):
899 | { expr: EThrow(map(e1)), pos: e.pos };
900 | case TMeta(m, e1):
901 | { expr: EMeta(m, map(e1)), pos: e.pos };
902 | case TWhile(econd,eblock,normal):
903 | { expr:EWhile(map(econd),map(eblock),normal), pos:e.pos };
904 | case TCast(e1,_):
905 | var t = toComplexType(e.t);
906 | var e1 = map(e1);
907 | macro @:pos(e.pos) ( (cast $e1) : $t );
908 | case TFor(v,e1,e2):
909 | var e1 = map(e1);
910 | var e2 = map(e2);
911 | { expr: EFor(macro $i{v.name} in $e1, e2), pos:e.pos };
912 | case TSwitch(econd, cases, edef):
913 | var last = inswitch;
914 | inswitch = true;
915 | var ret = { expr: ESwitch( map(econd), [ for (c in cases) { values: [ for (e in c.values) map(e) ], expr: map(c.expr) } ], edef == null ? null : map(edef) ), pos:e.pos };
916 | inswitch = last;
917 | ret;
918 | case TTry(etry, catches):
919 | { expr: ETry(map(etry), [ for (c in catches) { name: c.v.name, type: toComplexType(c.v.t), expr: map(c.expr) } ]), pos: e.pos };
920 | }
921 | }
922 | return map(e);
923 | }
924 |
925 | private function exprModule(m:ModuleType,pos:Position):Expr
926 | {
927 | var base:BaseType = switch(m) {
928 | case TClassDecl(c):
929 | c.get();
930 | case TEnumDecl(e):
931 | e.get();
932 | case TTypeDecl(t):
933 | t.get();
934 | case TAbstract(a):
935 | a.get();
936 | };
937 | if (base.isPrivate)
938 | {
939 | // create a helper typedef
940 | var clsnum = packs.get(pack);
941 | if (clsnum == null)
942 | clsnum = 0;
943 | packs[pack] = clsnum + 1;
944 | var pack = pack.split('.'),
945 | name = base.name + "_Access_" + clsnum;
946 | var tparams = [for(p in base.params) tdynamic];
947 | var type = switch (m) {
948 | case TClassDecl(c):
949 | TInst(c,tparams);
950 | case TEnumDecl(e):
951 | TEnum(e,tparams);
952 | case TTypeDecl(t):
953 | TType(t,tparams);
954 | case TAbstract(a):
955 | TAbstract(a,tparams);
956 | };
957 |
958 | defineType({ pack:pack, name:name, pos:pos, kind: TDAlias( toComplexType(type) ), fields:[] });
959 | if (pack.length == 0)
960 | return macro @:pos(pos) $i{name};
961 | var expr = macro @:pos(pos) $i{pack[0]};
962 | for (i in 1...pack.length)
963 | {
964 | var p = pack[i];
965 | expr = macro @:pos(pos) $expr.$p;
966 | }
967 | expr = macro @:pos(pos) $expr.$name;
968 | return expr;
969 | } else {
970 | return getTypedExpr({ expr: TTypeExpr(m), t:tdynamic, pos:pos });
971 | }
972 | }
973 |
974 | private static function toComplexType(t:Type):ComplexType
975 | {
976 | // we need this function because there are some types that aren't compatible with toComplexType
977 | // for example, TMonos and private types
978 | // For TMonos, we'll transform them into Dynamic; For private types, we'll use unihx._internal.PrivateTypeAccess
979 | var params = null;
980 | var base:BaseType = switch (t.follow()) {
981 | case TInst(c,p):
982 | params = p;
983 | c.get();
984 | case TEnum(c,p):
985 | params = p;
986 | c.get();
987 | case TAbstract(c,p):
988 | params = p;
989 | c.get();
990 | case TMono(_):
991 | return macro : Dynamic;
992 | case _:
993 | null;
994 | }
995 | return if (base != null && base.isPrivate)
996 | {
997 | // use PrivateTypeAccess
998 | var t = base.module,
999 | name = base.name;
1000 | var pvtAcc = macro : unihx._internal.PrivateTypeAccess;
1001 | switch (pvtAcc) {
1002 | case TPath(p):
1003 | p.params = [TPExpr( macro $v{t} ), TPExpr( macro $v{name} )];
1004 | for (param in params)
1005 | {
1006 | p.params.push(TPType( toComplexType(param) ));
1007 | }
1008 | case _: throw "assert";
1009 | }
1010 | pvtAcc;
1011 | } else {
1012 | t.toComplexType();
1013 | }
1014 | }
1015 |
1016 | private static function getVarName(v:TVar)
1017 | {
1018 | if (v.id == -1 && v.name == "this") return "parent";
1019 | var name = if (v.name.startsWith('`')) 'tmp' else v.name;
1020 | return name + '__' + v.id;
1021 | }
1022 |
1023 | private static function collectTParams(type:Type, collected:Map)
1024 | {
1025 | while(true)
1026 | {
1027 | switch(type) {
1028 | case TMono(t):
1029 | var t = t.get();
1030 | if (t != null)
1031 | {
1032 | type = t;
1033 | continue;
1034 | }
1035 | case TEnum(_,params):
1036 | for (p in params) collectTParams(p,collected);
1037 | case TType(_,params):
1038 | for (p in params) collectTParams(p,collected);
1039 | case TFun(args,ret):
1040 | for (arg in args) collectTParams(arg.t,collected);
1041 | collectTParams(ret, collected);
1042 | case TAnonymous(a):
1043 | for (f in a.get().fields)
1044 | collectTParams(f.type,collected);
1045 | case TDynamic(t):
1046 | if (t != null)
1047 | {
1048 | type = t;
1049 | continue;
1050 | }
1051 | case TLazy(f):
1052 | type = f();
1053 | case TAbstract(_,params):
1054 | for (p in params) collectTParams(p,collected);
1055 | case TInst(_.get() => cl, params):
1056 | switch(cl.kind) {
1057 | case KTypeParameter(_):
1058 | collected[cl.name] = type;
1059 | return;
1060 | case _:
1061 | }
1062 | for (p in params) collectTParams(p,collected);
1063 | }
1064 | break;
1065 | }
1066 | }
1067 |
1068 | private function getMaxId()
1069 | {
1070 | var max = 0;
1071 | var len = cfgs.length;
1072 | while (len --> 0)
1073 | {
1074 | var c = cfgs[len];
1075 | max = c.id;
1076 | if (c.block.length != 0 || c.next != null)
1077 | {
1078 | break;
1079 | }
1080 | }
1081 | return max;
1082 | }
1083 |
1084 | private function followId(i:Int)
1085 | {
1086 | var cfg = cfgs[i];
1087 | while (cfg != null && cfg.block.length == 0 && cfg.next != null)
1088 | {
1089 | cfg = cfgs[cfg.next];
1090 | i = cfg.id;
1091 | }
1092 | return i;
1093 | }
1094 | }
1095 |
1096 | typedef FlowGraph = { block:Array, tryctx:Array<{ t:Type, gotoHandler:TypedExpr }>, next:Null, id:Int };
1097 |
--------------------------------------------------------------------------------
/unihx/_internal/editor/AllowDragDrop.hx:
--------------------------------------------------------------------------------
1 | package unihx._internal.editor;
2 | import unityengine.*;
3 | import unityeditor.*;
4 | import haxe.ds.Vector;
5 | using StringTools;
6 |
7 | @:meta(UnityEditor.CustomEditor(typeof(UnityEngine.Transform)))
8 | @:meta(UnityEditor.CanEditMultipleObjects)
9 | @:nativeGen
10 | @:native('AllowDragDrop')
11 | class AllowDragDrop extends Editor
12 | {
13 | private var _target(get,never):Transform;
14 |
15 | private function OnEnable()
16 | {
17 | Repaint();
18 | }
19 |
20 | inline private function get__target():Transform
21 | {
22 | return cast this.target;
23 | }
24 |
25 | @:overload override public function OnInspectorGUI()
26 | {
27 | var obj = DragAndDrop.objectReferences;
28 | if (obj == null || obj.Length == 0)
29 | return;
30 | switch(Event.current.type)
31 | {
32 | case DragUpdated | DragExited if (AssetDatabase.GetAssetPath(DragAndDrop.objectReferences[0]).endsWith('.hx')):
33 | DragAndDrop.visualMode = Link;
34 | Event.current.Use();
35 | case DragPerform if (AssetDatabase.GetAssetPath(DragAndDrop.objectReferences[0]).endsWith('.hx')):
36 | DragAndDrop.visualMode = Link;
37 | DragAndDrop.AcceptDrag();
38 | Event.current.Use();
39 | var ret = _target.gameObject.AddComponent(DragAndDrop.objectReferences[0].name);
40 | if (ret == null)
41 | EditorUtility.DisplayDialog('Can\'t add script','Can\'t add script behaviour "${DragAndDrop.objectReferences[0].name}"',"OK");
42 | case _:
43 | super.OnInspectorGUI();
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/unihx/_internal/editor/AssetProcessor.hx:
--------------------------------------------------------------------------------
1 | package unihx._internal.editor;
2 | import haxe.ds.Vector;
3 | import sys.FileSystem.*;
4 | import haxe.io.Path;
5 | import unityengine.*;
6 | import Std.*;
7 | import cs.system.reflection.BindingFlags;
8 |
9 | using StringTools;
10 |
11 | @:nativeGen @:keep class AssetProcessor extends unityeditor.AssetPostprocessor
12 | {
13 | static function OnPostprocessAllAssets(
14 | importedAssets:Vector,
15 | deletedAssets:Vector,
16 | movedAssets:Vector,
17 | movedFromAssetPaths:Vector)
18 | {
19 | var sources = [],
20 | deleted = [],
21 | refresh = false;
22 | for (str in importedAssets)
23 | {
24 | if (str.endsWith(".hx"))
25 | sources.push(str);
26 | }
27 | for (str in movedAssets)
28 | {
29 | if (str.endsWith(".hx"))
30 | sources.push(str);
31 | }
32 |
33 | for (d in movedFromAssetPaths)
34 | {
35 | if (d.endsWith(".hx"))
36 | {
37 | deleted.push(d);
38 | }
39 | }
40 | for (d in deletedAssets)
41 | {
42 | if (d.endsWith(".hx"))
43 | {
44 | deleted.push(d);
45 | }
46 | }
47 |
48 | for (d in deleted)
49 | {
50 | //delete also .cs file
51 | var path = Path.directory(d) + '/hx-compiled/' + Path.withoutDirectory(d).substr(0,-2) + "cs";
52 | if (exists( path ))
53 | {
54 | deleteFile(path);
55 | if (exists( path + '.meta' ))
56 | deleteFile( path + '.meta' );
57 | if (readDirectory( Path.directory(d) + '/hx-compiled' ).length == 0)
58 | deleteDirectory( Path.directory(d) + '/hx-compiled' );
59 | refresh = true;
60 | }
61 | }
62 | if (sources.length > 0)
63 | {
64 | refresh = true;
65 | var comp = HaxeProperties.props();
66 | var success = comp.compile(['--cwd','./Assets','build.hxml','--macro','unihx._internal.Compiler.compile()']);
67 | }
68 | if (refresh)
69 | {
70 | unityeditor.AssetDatabase.Refresh();
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/unihx/_internal/editor/HaxeCompiler.hx:
--------------------------------------------------------------------------------
1 | package unihx._internal.editor;
2 | import unihx._internal.editor.HaxeProperties;
3 | import sys.io.Process;
4 | import unityengine.*;
5 | import Std.*;
6 |
7 | using StringTools;
8 |
9 | class HaxeCompiler
10 | {
11 | public var props(default,null):Comp;
12 | var process:Process;
13 |
14 | public function new(prop:Comp)
15 | {
16 | this.props = prop;
17 | switch(prop)
18 | {
19 | case CompilationServer(port):
20 | newProcess(port);
21 | case _:
22 | }
23 | }
24 |
25 | function newProcess(port:Int)
26 | {
27 | if (process != null)
28 | {
29 | try
30 | {
31 | process.kill();
32 | process.close();
33 | }
34 | catch(e:Dynamic) {}
35 | }
36 | process = null;
37 | process = new Process('haxe',['--wait',port + ""]);
38 | }
39 |
40 | public function compile(args:Array, verbose=false):Bool
41 | {
42 | var cmd = switch(props)
43 | {
44 | case DontCompile:
45 | return true;
46 | case Compile:
47 | trace('compile',args);
48 | new Process("haxe",args);
49 | case CompilationServer(port):
50 | if (process == null || ( untyped process.native : cs.system.diagnostics.Process ).HasExited )
51 | newProcess(port);
52 | args = args.copy();
53 | args.push('--connect'); args.push(port+"");
54 | trace('compile',args);
55 | new Process('haxe',args);
56 | }
57 |
58 | var ret = true;
59 | if (cmd != null)
60 | {
61 | var sw = new cs.system.diagnostics.Stopwatch();
62 | sw.Start();
63 | if (cmd.exitCode() != 0)
64 | {
65 | ret = false;
66 | Debug.LogError("Haxe compilation failed.");
67 | }
68 | sw.Stop();
69 | if (verbose)
70 | Debug.Log('Compilation ended (' + sw.Elapsed + ")" );
71 | for (ln in cmd.stdout.readAll().toString().trim().split('\n'))
72 | {
73 | var ln = ln.trim();
74 | if (ln != "")
75 | Debug.Log(ln);
76 | }
77 | for (ln in cmd.stderr.readAll().toString().trim().split('\n'))
78 | {
79 | var ln = ln.trim();
80 |
81 | if (ln == "") continue;
82 | if (ln.startsWith('Warning'))
83 | Debug.LogWarning(ln);
84 | else
85 | reportError(ln);
86 | }
87 | }
88 | return ret;
89 | }
90 |
91 | public function close()
92 | {
93 | if (process != null)
94 | {
95 | process.kill();
96 | process.close();
97 | process = null;
98 | }
99 | }
100 |
101 | public static function reportError(line:String)
102 | {
103 | var ln = line.split(':');
104 | ln.reverse();
105 | var file = ln.pop(),
106 | lineno = parseInt(ln.pop()),
107 | other = ln.pop(),
108 | rest = ln.join(":");
109 |
110 | var fullp = cs.system.io.Path.GetFullPath(cs.system.io.Path.Combine("Assets",file));
111 | var debug = cs.Lib.toNativeType(Debug);
112 | try
113 | {
114 | Debug.LogException(new HaxeError(line,fullp,lineno));
115 | }
116 | catch(e:Dynamic)
117 | {
118 | Debug.LogError(line);
119 | }
120 | }
121 | }
122 |
123 | @:nativeGen class HaxeError extends cs.system.Exception
124 | {
125 | var file:String;
126 | var line:Int;
127 | var msg:String;
128 | public function new(msg:String,file:String,line:Int)
129 | {
130 | super(msg);
131 | this.msg = msg;
132 | this.file = file;
133 | this.line = line;
134 | }
135 |
136 | @:overload override private function get_Message():String
137 | {
138 | return msg;
139 | }
140 |
141 | @:overload override private function get_StackTrace():String
142 | {
143 | return "(at " + file + ":" + line + ")";
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/unihx/_internal/editor/HaxeProperties.hx:
--------------------------------------------------------------------------------
1 | package unihx._internal.editor;
2 | import unityengine.*;
3 | import unityeditor.*;
4 | import unihx.inspector.*;
5 | import cs.system.net.sockets.*;
6 | import cs.system.net.*;
7 | import sys.FileSystem.*;
8 |
9 | using StringTools;
10 |
11 | @:nativeGen
12 | @:native('HaxeProperties')
13 | class HaxeProperties extends EditorWindow
14 | {
15 | public var scroll:Vector2;
16 | @:meta(UnityEditor.MenuItem("Window/Haxe Properties"))
17 | public static function showWindow()
18 | {
19 | EditorWindow.GetWindow(cs.Lib.toNativeType(HaxeProperties));
20 | }
21 |
22 | @:meta(UnityEditor.MenuItem("Assets/Create/Haxe Script"))
23 | public static function createHaxeClass()
24 | {
25 | var path = AssetDatabase.GetAssetPath (Selection.activeObject);
26 | if (path == "")
27 | {
28 | path = "Assets";
29 | }
30 |
31 | if (exists('$path/NewHaxeBehaviour.hx'))
32 | {
33 | var n = 0;
34 | while (exists('$path/NewHaxeBehaviour${++n}.hx')) {}
35 | path = '$path/NewHaxeBehaviour$n.hx';
36 | } else {
37 | path = '$path/NewHaxeBehaviour.hx';
38 | }
39 | sys.io.File.saveContent(path, 'import unityengine.*;\nclass NewHaxeBehaviour extends HaxeBehaviour\n{\n\tfunction Update()\n\t{\n\t}\n}');
40 |
41 | unityeditor.AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
42 | EditorUtility.FocusProjectWindow();
43 | }
44 |
45 | function OnEnable()
46 | {
47 | props();
48 | }
49 |
50 | function OnDisable()
51 | {
52 | props().close();
53 | }
54 |
55 | function OnGUI()
56 | {
57 | var arr = new cs.NativeArray(1);
58 | arr[0] = GUILayout.MaxHeight(300);
59 | // arr[1] = GUILayout.MaxWidth(300);
60 | GUILayout.BeginVertical(arr);
61 | scroll = GUILayout.BeginScrollView(scroll, new cs.NativeArray(0));
62 | props().OnGUI();
63 | GUILayout.EndScrollView();
64 | if (GUILayout.Button("Save",null))
65 | {
66 | props().save();
67 | }
68 | if (GUILayout.Button("Reload",null))
69 | {
70 | props().reload();
71 | }
72 | if (GUILayout.Button("Force recompile",null))
73 | {
74 | props().compile(['--cwd','./Assets','params.hxml','--macro','unihx._internal.Compiler.compile()']);
75 | unityeditor.AssetDatabase.Refresh();
76 | }
77 | GUILayout.EndVertical();
78 | }
79 |
80 | public static function props():HaxePropertiesData
81 | {
82 | return HaxePropertiesData.get();
83 | }
84 | }
85 |
86 | class HaxePropertiesData implements InspectorBuild
87 | {
88 | /**
89 | Choose how will Haxe classes be compiled
90 | **/
91 | public var compilation:Comp;
92 |
93 | public var _:Space;
94 |
95 | public var verbose:Bool;
96 |
97 | /**
98 | Extra Haxe parameters from build.hxml
99 | @label Extra parameters
100 | **/
101 | public var _:ConstLabel;
102 |
103 | /**
104 | Extra Haxe parameters from build.hxml
105 | @min-height 200
106 | **/
107 | public var extraParams:TextArea;
108 |
109 | private var compiler:HaxeCompiler;
110 |
111 | private static var current:HaxePropertiesData;
112 |
113 | public static function get()
114 | {
115 | if (current == null)
116 | return current = new HaxePropertiesData().reload();
117 | return current;
118 | }
119 |
120 | public function reload():HaxePropertiesData
121 | {
122 | if (exists('Assets/build.hxml'))
123 | {
124 | reloadFrom( sys.io.File.read('Assets/build.hxml') );
125 | } else { //create
126 | save();
127 | }
128 | return this;
129 | }
130 |
131 | public function compile(args)
132 | {
133 | if (compiler == null)
134 | reload();
135 | if (compiler == null)
136 | compiler = new HaxeCompiler(compilation);
137 |
138 | return compiler.compile(args);
139 | }
140 |
141 | public function close()
142 | {
143 | current = null;
144 | if (compiler != null)
145 | compiler.close();
146 | compiler = null;
147 | }
148 |
149 | private function getSaveContents()
150 | {
151 | var b = new StringBuf();
152 | if (extraParams == null || extraParams == "")
153 | b.add("# Add your own compiler parameters here\n\n");
154 | switch(compilation)
155 | {
156 | case CompilationServer(p):
157 | if (p < 1024)
158 | p = availablePort();
159 | b.add('params.hxml\n#--connect $p\n');
160 | case Compile:
161 | b.add('params.hxml\n');
162 | case DontCompile:
163 | }
164 | if (verbose)
165 | b.add('#verbose\n');
166 | b.add('\n');
167 | if (extraParams != null)
168 | b.add(extraParams);
169 | return b.toString();
170 | }
171 |
172 | public function save()
173 | {
174 | var w = sys.io.File.write('Assets/build.hxml');
175 | w.writeString(getSaveContents());
176 | w.close();
177 |
178 | if (this.compiler == null || !Type.enumEq(this.compiler.props, this.compilation))
179 | {
180 | if (this.compiler != null)
181 | this.compiler.close();
182 | this.compiler = new HaxeCompiler(this.compilation);
183 | }
184 | }
185 |
186 | private function reloadFrom(i:haxe.io.Input)
187 | {
188 | var comp = DontCompile,
189 | buf = new StringBuf();
190 | verbose = false;
191 | try
192 | {
193 | var regex = ~/[ \t]+/g;
194 | while(true)
195 | {
196 | var ln = i.readLine().trim();
197 | var cmd = regex.split(ln);
198 | switch (cmd[0])
199 | {
200 | case '--connect' | '#--connect':
201 | var portCmd = cmd[1].split(":");
202 | var port = if (portCmd.length == 1)
203 | Std.parseInt(portCmd[0]);
204 | else
205 | Std.parseInt(portCmd[1]);
206 | comp = CompilationServer(port);
207 | case '#verbose':
208 | verbose = true;
209 | case 'params.hxml':
210 | if (comp == DontCompile)
211 | comp = Compile;
212 | default:
213 | buf.add(ln);
214 | buf.add("\n");
215 | }
216 | }
217 | }
218 | catch(e:haxe.io.Eof) {}
219 | if (this.compilation == null || !Type.enumEq(this.compilation,comp))
220 | {
221 | if (this.compiler != null)
222 | this.compiler.close();
223 | this.compiler = new HaxeCompiler(comp);
224 | }
225 |
226 | this.compilation = comp;
227 | this.extraParams = buf.toString().trim();
228 | }
229 |
230 | function new()
231 | {
232 | }
233 |
234 | private static function availablePort()
235 | {
236 | var l = new TcpListener(IPAddress.Loopback,0);
237 | l.Start();
238 | var port = cast(l.LocalEndpoint, IPEndPoint).Port;
239 | l.Stop();
240 | return port;
241 | }
242 | }
243 |
244 | enum Comp
245 | {
246 | /**
247 | @label Don't compile
248 | **/
249 | DontCompile;
250 | /**
251 | @label Use standard Haxe compiler
252 | **/
253 | Compile;
254 | /**
255 | @label Use compilation server
256 | **/
257 | CompilationServer(port:Int);
258 | }
259 |
--------------------------------------------------------------------------------
/unihx/inspector/AnimationCurve.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | /**
4 | A field for editing an AnimationCurve.
5 | Options:
6 | - range (left,top,width,height) : optional rectangle that the curve is restrained within
7 | - color #RRGGBBAA : color
8 | **/
9 | typedef AnimationCurve = unityengine.AnimationCurve;
10 |
--------------------------------------------------------------------------------
/unihx/inspector/Button.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | typedef Button = Bool;
4 |
--------------------------------------------------------------------------------
/unihx/inspector/Color.hx:
--------------------------------------------------------------------------------
1 | package unihx.inpector;
2 |
3 | typedef Color = unityengine.Color;
4 |
--------------------------------------------------------------------------------
/unihx/inspector/ConstLabel.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | //@selectable = SelectableLabel
4 | typedef ConstLabel = Void;
5 |
--------------------------------------------------------------------------------
/unihx/inspector/Fold.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | typedef Fold = T;
4 |
--------------------------------------------------------------------------------
/unihx/inspector/InspectorBuild.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | @:autoBuild(unihx.inspector.Macro.build("OnGUI"))
4 | interface InspectorBuild
5 | {
6 | function OnGUI():Void;
7 | }
8 |
--------------------------------------------------------------------------------
/unihx/inspector/IntField.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | typedef IntField = Int;
4 |
--------------------------------------------------------------------------------
/unihx/inspector/Label.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | //@selectable = SelectableLabel
4 | typedef Label = String;
5 |
--------------------------------------------------------------------------------
/unihx/inspector/Layer.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | abstract Layer(Int) from Int to Int
4 | {
5 | @:extern inline public function toInt():Int
6 | {
7 | return this;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/unihx/inspector/Macro.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 | #if macro
3 | import haxe.macro.Expr;
4 | import haxe.macro.Type;
5 | import haxe.macro.Context.*;
6 | import sys.FileSystem.*;
7 |
8 | using haxe.macro.Tools;
9 | using StringTools;
10 | using Lambda;
11 | #end
12 |
13 | class Macro
14 | {
15 | macro public static function prop(ethis:Expr, efield:Expr)
16 | {
17 | var field = switch efield.expr {
18 | case EConst(CIdent(s)) | EConst(CString(s)):
19 | s;
20 | case _:
21 | throw new Error("This argument must either be a constant string or a constant identifier", efield.pos);
22 | };
23 |
24 | var cf = switch typeof(ethis).follow() {
25 | case TInst(_.get() => c,_):
26 | function loop(c:ClassType)
27 | {
28 | var f = c.fields.get().find(function (cf) return cf.name == field);
29 | if (f == null)
30 | {
31 | if (c.superClass == null)
32 | return null;
33 | return loop( c.superClass.t.get() );
34 | } else {
35 | return f;
36 | }
37 | }
38 | loop(c);
39 | case TAnonymous(_.get() => a):
40 | a.fields.find(function (cf) return cf.name == field);
41 | case t:
42 | throw new Error('Only class instances or anonymous types can be used, but the type was ' + t.toString(), ethis.pos);
43 | };
44 |
45 | if (cf == null)
46 | throw new Error('Field $field was not found at ${typeof(ethis).toString()}',currentPos());
47 | var ret = exprFromType(ethis,cf);
48 | if (ret == null)
49 | return macro null;
50 | else
51 | return ret;
52 | }
53 |
54 | #if macro
55 | public static function build(fieldName:Null):Array
56 | {
57 | if (defined('display'))
58 | return null;
59 | var fields = getBuildFields(),
60 | pos = currentPos();
61 | var addedFields = [];
62 | var ctorAdded = [],
63 | ctor = null;
64 |
65 | for (f in fields)
66 | {
67 | if (f.name == "new") ctor = f;
68 | if (f.access.has(AStatic))
69 | continue;
70 | switch f.kind {
71 | case FVar(t,e):
72 | if (!f.meta.exists(function(v) return v.name == ":skip") && f.access.has(APublic))
73 | addedFields.push(f);
74 | if (e == null)
75 | {
76 | switch t {
77 | case TAnonymous(fields):
78 | var objDecl = [];
79 | for (f in fields)
80 | {
81 | switch f.kind {
82 | case FVar(_,null):
83 | objDecl.push({ field:f.name, expr: macro @:pos(f.pos) cast null });
84 | case FVar(t,e):
85 | objDecl.push({ field:f.name, expr: e });
86 | f.kind = FVar(t,null);
87 | case _:
88 | }
89 | }
90 | e = { expr:EObjectDecl(objDecl), pos:f.pos };
91 | case null | _:
92 | }
93 | }
94 |
95 | if (e != null)
96 | {
97 | var ethis = { expr: EField(macro this, f.name), pos:f.pos };
98 | ctorAdded.push(macro $ethis = $e);
99 | f.kind = FVar(t,null);
100 | }
101 | case FProp(get,set,t,e):
102 | if (!f.meta.exists(function(v) return v.name == ":skip") && f.access.has(APublic))
103 | addedFields.push(f);
104 | if (e != null)
105 | {
106 | var ethis = { expr: EField(macro this, f.name), pos:f.pos };
107 | ctorAdded.push(macro $ethis = $e);
108 | f.kind = FProp(get,set,t,null);
109 | }
110 | case _:
111 | }
112 | }
113 |
114 | function filter(f:Field)
115 | {
116 | switch (f.kind)
117 | {
118 | case FVar(t,_) | FProp(_,_,t,_):
119 | var t = t.toType();
120 | if (t != null) switch (t.follow())
121 | {
122 | case TAbstract(_.get() => { pack:[], name:"Void" },_):
123 | return false;
124 | case _:
125 | return true;
126 | }
127 | case _:
128 | }
129 | return true;
130 | }
131 |
132 | var f2 = fields.filter(filter);
133 | var i = 0;
134 | for (f in addedFields)
135 | if (f.name == "_")
136 | f.name = "_" + i++;
137 |
138 | if (fields.exists(function (cf) return cf.name == fieldName))
139 | {
140 | if (ctorAdded.length == 0 && f2.length == fields.length)
141 | return null;
142 | } else {
143 | switch ComplexType.TAnonymous(addedFields).toType() {
144 | case TAnonymous(_.get() => f):
145 | var complex = getLocalType().toComplexType();
146 | var allfields = [],
147 | ethis = if (fieldName == null)
148 | macro ( (cast this.target) : $complex);
149 | else
150 | macro this;
151 | var fs = [ for (f in f.fields) f.name => f ];
152 | for (cf in addedFields)
153 | {
154 | var ethis = { expr:EField(ethis, cf.name), pos:pos };
155 | var expr = exprFromType(ethis, fs[cf.name]);
156 | if (expr == null)
157 | continue;
158 |
159 | changePos(expr,cf.pos);
160 | allfields.push(expr);
161 | }
162 | var block = { expr:EBlock(allfields), pos:pos };
163 | var td = macro class extends unityeditor.Editor { @:overload public function OnGUI() $block; };
164 |
165 | if (fieldName == null)
166 | {
167 | var cl = getLocalClass().get();
168 | allfields.push(macro unityeditor.EditorUtility.SetDirty(this.target));
169 | // trace(block.toString());
170 | switch macro @:meta(UnityEditor.CustomEditor(typeof($i{cl.name}))) "" {
171 | case { expr:EMeta(m,_) }:
172 | td.meta = [m];
173 | case _: throw "assert";
174 | }
175 |
176 | if (cl.meta.has(':editMulti'))
177 | {
178 | switch macro @:meta(UnityEditor.CanEditMultipleObjects) "" {
179 | case { expr:EMeta(m,_) }:
180 | td.meta.push(m);
181 | case _: throw "assert";
182 | }
183 | }
184 |
185 | //define type
186 | td.name = cl.name + '_Helper__';
187 | td.pack = cl.pack.copy();
188 | td.pack.push('editor');
189 | td.fields[0].access.push(AOverride);
190 | td.fields[0].name = "OnInspectorGUI";
191 | f2 = f2.filter(function(f) {
192 | if (f.meta.exists(function(m) return m.name == ":editor"))
193 | {
194 | switch (f.kind) {
195 | case FFun(fun) if (fun.expr != null):
196 | function map(e:Expr)
197 | {
198 | switch(e.expr)
199 | {
200 | case EConst(CIdent("this")):
201 | return ethis;
202 | case EConst(CIdent(id)):
203 | return try getTypedExpr( typeExpr(e) ) catch(exc:Dynamic) e;
204 | case _:
205 | return e.map(map);
206 | }
207 | }
208 | fun.expr = map(fun.expr);
209 | case _:
210 | }
211 | td.fields.push(f);
212 | return false;
213 | } else {
214 | return true;
215 | }
216 | });
217 | if (cl.pack.length != 0)
218 | {
219 | cl.meta.add(':native', [macro $v{cl.name}], cl.pos);
220 | }
221 | try {
222 | defineType(td);
223 | } catch(e:Dynamic) { trace(e); }
224 | } else {
225 | td.fields[0].name = fieldName;
226 | f2.push(td.fields[0]);
227 | }
228 | case _: throw "assert";
229 | }
230 | }
231 |
232 | if (ctorAdded.length > 0)
233 | {
234 | if (ctor == null)
235 | {
236 | var sup = getSuper(getLocalClass()),
237 | block = [],
238 | expr = { expr:EBlock(block), pos:pos };
239 | var kind = sup == null || sup.length == 0 ? FFun({ args:[], ret:null, expr:expr}) : FFun({ args:[ for (s in sup) { name:s.name, opt:s.opt, type:null } ], ret:null, expr:expr });
240 | if (sup != null)
241 | {
242 | block.push({ expr:ECall(macro super, [ for (s in sup) macro $i{s.name} ]), pos:pos });
243 | }
244 |
245 | ctor = { name: "new", access: [APublic], pos:pos, kind:kind };
246 | f2.push(ctor);
247 | }
248 | switch ctor.kind {
249 | case FFun(fn):
250 | var arr = null;
251 | switch fn.expr {
252 | case { expr: EBlock(bl) }:
253 | arr = bl;
254 | case _:
255 | fn.expr = { expr: EBlock( arr = [fn.expr] ), pos: pos };
256 | }
257 | for (added in ctorAdded)
258 | arr.push(added);
259 | case _: throw "assert";
260 | }
261 | }
262 | return f2;
263 | }
264 |
265 | private static function getSuper(cls:Ref)
266 | {
267 | var sup = cls.get().superClass;
268 | if (sup == null)
269 | return null;
270 |
271 | var ctor = sup.t.get().constructor;
272 | if (ctor == null)
273 | return getSuper(sup.t);
274 | return switch ctor.get().type.follow() {
275 | case TFun(args,_):
276 | args;
277 | case _: throw "assert";
278 | }
279 | }
280 |
281 | private static function changePos(e:Expr,p)
282 | {
283 | function iter(e:Expr)
284 | {
285 | e.pos = p;
286 | e.iter(iter);
287 | }
288 | iter(e);
289 | }
290 |
291 | private static function exprFromType(ethis:Expr, field:ClassField, ?type):Expr
292 | {
293 | if (field == null) return null;
294 | if (type == null) type = field.type;
295 | var pos = field.pos;
296 | var pack = null,
297 | name = null,
298 | params = null,
299 | etype = null;
300 | switch type {
301 | case TMono(r) if (r != null):
302 | exprFromType(ethis,field,r.get());
303 |
304 | case TMono(_) | TDynamic(_):
305 | // pack = []; name = "Dynamic"; params = [];
306 | // throw new Error('Unsupported Dynamic',pos);
307 | return null;
308 | case TEnum(e,p):
309 | var e = e.get();
310 | etype = e;
311 | pack = e.pack; name = e.name; params = p;
312 | case TInst(c,p):
313 | var c = c.get();
314 | pack = c.pack; name = c.name; params = p;
315 | case TAnonymous(a):
316 | var a = a.get();
317 | var fields = a.fields;
318 | fields.sort(function(v1,v2) return Reflect.compare(getPosInfos(v1.pos).min, getPosInfos(v2.pos).min));
319 | var arr = [];
320 | for (cf in fields)
321 | {
322 | var e = exprFromType(ethis,cf);
323 | if (e != null)
324 | arr.push(e);
325 | }
326 | return { expr: EBlock(arr), pos: pos };
327 | case TFun(_,_):
328 | // throw new Error('Unsupported function',pos);
329 | return null;
330 |
331 | case TAbstract(t,p):
332 | var t = t.get();
333 | pack = t.pack; name = t.name; params = p;
334 | case TType(_.get() => { pack:['unihx','inspector'], name:n },p):
335 | pack = ['unihx','inspector']; name = n; params = p;
336 |
337 | case TType(_,_):
338 | return exprFromType(ethis, field, follow(type,true));
339 | case _:
340 | return null;
341 | // case _: throw new Error('assert',pos);
342 | }
343 |
344 | var unity = false,
345 | inspector = false;
346 | switch pack {
347 | case ['unityengine']:
348 | unity = true;
349 | case ['unihx','inspector']:
350 | unity = true;
351 | inspector = true;
352 | case _:
353 | }
354 |
355 | var docs = field.doc != null ? [ for (c in parseComments(field.doc)) (c.tag == null ? "" : c.tag.trim()) => c.contents.trim() ] : new Map();
356 |
357 | var label = docs.get('label');
358 | if (label == null)
359 | label = toSep(field.name, ' '.code);
360 | var tooltip = docs[''];
361 | var guiContent = if (tooltip == null)
362 | {
363 | // macro $v{label};
364 | macro new unityengine.GUIContent($v{label});
365 | } else {
366 | macro new unityengine.GUIContent($v{label}, $v{tooltip});
367 | }
368 |
369 | var opts = field.doc == null ? null : nativeArray(getOptions(docs, field.pos), pos);
370 | if (opts == null)
371 | opts = macro null;
372 | // opts = macro new cs.NativeArray(0);
373 |
374 | switch name {
375 | case 'Vector2' if (unity):
376 | return macro $ethis = unityeditor.EditorGUILayout.Vector2Field($guiContent, $ethis, $opts);
377 | case 'Vector3' if (unity):
378 | return macro $ethis = unityeditor.EditorGUILayout.Vector3Field($guiContent, $ethis, $opts);
379 | case 'Vector4' if (unity):
380 | return macro $ethis = unityeditor.EditorGUILayout.Vector4Field($guiContent, $ethis, $opts);
381 | case 'AnimationCurve' if (unity):
382 | var range = parseRect(docs['range']),
383 | color = parseColor(docs['color']);
384 | if (color == null)
385 | color = parseColor('green');
386 | if (range == null)
387 | return macro $ethis = unityeditor.EditorGUILayout.CurveField($guiContent, $ethis, $opts);
388 | else
389 | return macro $ethis = unityeditor.EditorGUILayout.CurveField($guiContent, $ethis, $color, $range, $opts);
390 | case 'Color' if (unity):
391 | return macro $ethis = unityeditor.EditorGUILayout.ColorField($guiContent, $ethis, $opts);
392 | case 'Int' if (pack.length == 0):
393 | return macro $ethis = unityeditor.EditorGUILayout.IntField($guiContent, $ethis, $opts);
394 | case 'Slider' if (inspector):
395 | switch params {
396 | case [ _.follow() => TAbstract(_.get() => { pack:[], name:name },_) ]: switch name {
397 | case "Int":
398 | return macro $ethis.value = unityeditor.EditorGUILayout.IntSlider($guiContent, $ethis.value, $ethis.minLimit, $ethis.maxLimit, $opts);
399 | case "Float" | "Single":
400 | return macro $ethis.value = unityeditor.EditorGUILayout.Slider($guiContent, $ethis.value, $ethis.minLimit, $ethis.maxLimit, $opts);
401 | case _:
402 | throw new Error("Invalid parameter for Slider: " + name, pos);
403 | }
404 | case _:
405 | throw new Error("Invalid parameter for Slider", pos);
406 | }
407 | case 'Layer' if (inspector):
408 | return macro $ethis = unityeditor.EditorGUILayout.LayerField($guiContent, $ethis, $opts);
409 | case 'Password' if (inspector):
410 | return macro $ethis = unityeditor.EditorGUILayout.PasswordField($guiContent, $ethis, $opts);
411 | case 'Range' if (inspector):
412 | return macro unityeditor.EditorGUILayout.MinMaxSlider($guiContent, $ethis.minValue, $ethis.maxValue, $ethis.minLimit, $ethis.maxLimit, $opts);
413 | case 'Rect' if (unity):
414 | return macro unityeditor.EditorGUILayout.RectField($guiContent, $ethis, $opts);
415 | case 'Select' if (inspector):
416 | return macro $ethis.selectedIndex = unityeditor.EditorGUILayout.Popup($guiContent, $ethis.selectedIndex, $ethis.options, $opts);
417 | case 'Space' if (inspector):
418 | return macro unityeditor.EditorGUILayout.Space();
419 | case 'Tag' if (inspector):
420 | return macro $ethis = unityeditor.EditorGUILayout.TagField($guiContent, $ethis, $opts);
421 | case 'Text' | 'String':
422 | return macro $ethis = unityeditor.EditorGUILayout.TextField($guiContent, $ethis, $opts);
423 | case 'ConstLabel':
424 | return macro unityeditor.EditorGUILayout.LabelField($guiContent, $opts);
425 | case 'TextArea' if (inspector):
426 | return macro $ethis = unityeditor.EditorGUILayout.TextArea($ethis, $opts);
427 | case 'Bool' if (pack.length == 0):
428 | return macro $ethis = unityeditor.EditorGUILayout.Toggle($guiContent, $ethis, $opts);
429 | case 'Button' if (inspector):
430 | var e = macro $ethis = unityengine.GUILayout.Button($guiContent, $opts);
431 | if (docs['onclick'] != null)
432 | {
433 | var parsed = parse(docs['onclick'], pos);
434 | return macro if ($e) $parsed;
435 | }
436 | return e;
437 | case _ if (field.type.unify( getType("unityengine.Object") )):
438 | var allowSceneObjects = parseBool(docs['scene-objects']),
439 | type = parse(pack.join(".") + (pack.length == 0 ? name : "." + name),pos);
440 | if (allowSceneObjects == null)
441 | allowSceneObjects = false;
442 | return macro $ethis = cast unityeditor.EditorGUILayout.ObjectField($guiContent, $ethis, cs.Lib.toNativeType($type), $v{allowSceneObjects}, $opts);
443 | case _ if (field.type.unify( getType('unihx.inspector.InspectorBuild') )):
444 | return macro if (ethis != null) $ethis.OnGUI();
445 | case _ if (etype != null):
446 | return macro $ethis = ${exprFromEnum(ethis, etype, type, guiContent, opts)};
447 | case _:
448 | return null;
449 | }
450 | }
451 |
452 | private static function exprFromEnum(ethis:Expr, e:EnumType, t:Type, label, opts):Expr
453 | {
454 | //ensure created helper class
455 | var tname = ensureEnumHelper(e,t,ethis.pos);
456 | return macro $tname.editorHelper($ethis, $label, $opts);
457 | }
458 |
459 | public static function buildEnumHelper(module:String, name:String)
460 | {
461 | var type = getModule(module).find(function(v) return switch(v.follow()) { case TEnum(e,_) if (e.get().name == name): true; case _: false; });
462 | var e = switch type {
463 | case TEnum(e,_):
464 | e.get();
465 | default:
466 | throw new Error("assert: not an enum : " + name, currentPos());
467 | };
468 | var pos = currentPos();
469 |
470 | // starting type definition
471 | var etype = type.toComplexType();
472 | var cases = [],
473 | guiContent = [],
474 | values = [];
475 | var i = 0;
476 | for (name in e.names)
477 | {
478 | var ctor = e.constructs.get(name);
479 | var docs = ctor.doc != null ? [ for (c in parseComments(ctor.doc)) (c.tag == null ? "" : c.tag.trim() == "arg" ? c.tag.trim() + "-" + c.contents.trim().split(' ')[0] : c.tag.trim()) => c.contents.trim() ] : new Map();
480 |
481 | var label = docs.get('label');
482 | if (label == null)
483 | label = toSep(ctor.name, ' '.code);
484 | // var ct = macro $v{label};
485 | var tooltip = docs[''];
486 | var ct = if (tooltip == null)
487 | {
488 | macro new unityengine.GUIContent($v{label});
489 | } else {
490 | macro new unityengine.GUIContent($v{label}, $v{tooltip});
491 | }
492 | guiContent.push(ct);
493 | values.push(macro $v{++i});
494 | switch ctor.type.follow() {
495 | case TEnum(_,_):
496 | cases.push( { values:[macro $v{i}], expr:macro return ${parse( etype.toString() + '.' + name, pos )}, guard:null } );
497 | case TFun(args,_):
498 | var exprs = [{ expr:EVars([ for (arg in args) { name:arg.name, expr:macro cast null, type:null } ]), pos:pos } ];
499 | exprs.push(macro unityeditor.EditorGUILayout.BeginHorizontal(null));
500 | exprs.push(macro unityeditor.EditorGUILayout.Space());
501 | exprs.push(macro unityeditor.EditorGUILayout.BeginVertical(null));
502 | exprs.push({ expr:ESwitch(
503 | macro current,
504 | [{
505 | values:[{ expr:ECall(macro $i{name}, [ for (arg in args) macro $i{arg.name + "_arg"} ]), pos:pos }],
506 | expr: { expr:EBlock([ for (arg in args) macro $i{arg.name} = $i{arg.name + "_arg" } ]), pos: pos }
507 | }],
508 | macro null),
509 | pos: pos });
510 | exprs.push( { expr:EVars([ for (arg in args) { name:arg.name + "__changed", expr:macro $i{arg.name}, type:null } ]), pos:pos } );
511 | for (arg in args)
512 | {
513 | var ret = exprFromType( (macro $i{arg.name + "__changed"}), {
514 | name: arg.name,
515 | type: arg.t,
516 | isPublic: true,
517 | params: [],
518 | meta: null,
519 | kind: FVar(AccNormal,AccNever),
520 | expr: null,
521 | pos: ctor.pos,
522 | doc: docs['arg-' + arg.name]
523 | });
524 | if (ret != null)
525 | exprs.push(ret);
526 | };
527 | exprs.push(macro unityeditor.EditorGUILayout.EndVertical());
528 | exprs.push(macro unityeditor.EditorGUILayout.EndHorizontal());
529 | var cond = macro popup != $v{i};
530 | for (arg in args)
531 | cond = macro $cond || !std.Type.enumEq($i{arg.name}, $i{arg.name + "__changed"});
532 | exprs.push(
533 | macro if ($cond)
534 | return ${ { expr:ECall(parse( etype.toString() + '.' + name, pos ), [ for (arg in args) macro $i{arg.name+"__changed"} ]), pos:pos } };
535 | else
536 | return current
537 | );
538 | cases.push( { values:[macro $v{i}], expr: { expr:EBlock(exprs), pos:pos }, guard:null } );
539 | case _:
540 | throw "assert";
541 | }
542 | }
543 | var eswitch = { expr:ESwitch(macro p2, cases, macro return null), pos: pos };
544 | var expr = macro {
545 | var popup = current == null ? 0 : std.Type.enumIndex(current) + 1;
546 | var guiContent = ${nativeArray(guiContent,pos)};
547 | var values = ${nativeArray(values,pos)};
548 | var p2 = unityeditor.EditorGUILayout.IntPopup( label, popup, guiContent, values, opts );
549 | $eswitch;
550 | return null;
551 | };
552 |
553 | var target = e.module.split('.').join('/') + ".hx";
554 | for (path in getClassPath())
555 | {
556 | if (exists(path + "/" + target))
557 | {
558 | registerModuleDependency(getLocalModule(), path + "/" + target);
559 | break;
560 | }
561 | }
562 |
563 | var td = macro class { public static function editorHelper( current:Null<$etype>, label:unityengine.GUIContent, opts:cs.NativeArray ) : Null<$etype> $expr; };
564 | return td.fields;
565 | }
566 |
567 | public static var enumHelpers = new Map();
568 |
569 | static function __init__()
570 | {
571 | enumHelpers = new Map();
572 | onMacroContextReused(function() {
573 | enumHelpers = new Map();
574 | return true;
575 | });
576 | }
577 |
578 | private static function ensureEnumHelper(e:EnumType, type:Type, pos:Position):Expr
579 | {
580 | if (e.params.length > 0)
581 | throw new Error("Enum with type parameters is currently unsupported",pos);
582 | var tname = e.pack.join('.') + (e.pack.length == 0 ? "" : ".") + e.name;
583 | if (!enumHelpers[tname])
584 | {
585 | var td = macro class { };
586 | switch macro @:build(unihx.inspector.Macro.buildEnumHelper($v{e.module}, $v{e.name})) "" {
587 | case { expr: EMeta(m,_) }:
588 | td.meta = [m];
589 | default: throw "assert";
590 | }
591 | td.name = e.name + "_Helper__";
592 | td.pack = e.pack;
593 | try {
594 | defineType(td);
595 | } catch(e:Dynamic) { trace(e); }
596 | enumHelpers[tname] = true;
597 | }
598 | // var t = try getType(tname + "_Helper__") catch(e:Dynamic) null;
599 | // if (t == null)
600 | return parse( tname + "_Helper__", pos );
601 | }
602 |
603 | private static function nativeArray(arr:Array,pos:Position):Expr
604 | {
605 | if (arr == null || arr.length == 0)
606 | return null;
607 | var ret = [];
608 | ret.push(macro var opts = new cs.NativeArray($v{arr.length}));
609 | for (i in 0...arr.length)
610 | {
611 | ret.push(macro opts[$v{i}] = ${arr[i]});
612 | }
613 | ret.push(macro opts);
614 | return { expr:EBlock(ret), pos:pos };
615 | }
616 |
617 | private static function getOptions(opts:Map,pos:Position):Array
618 | {
619 | var ret = [];
620 | var width = parseFloat(opts['width']),
621 | expandHeight = parseBool(opts['expand-height']),
622 | expandWidth = parseBool(opts['expand-width']),
623 | height = parseFloat(opts['height']),
624 | maxWidth = parseFloat(opts['max-width']),
625 | minWidth = parseFloat(opts['min-width']),
626 | maxHeight = parseFloat(opts['max-height']),
627 | minHeight = parseFloat(opts['min-height']);
628 |
629 | if (minHeight != null)
630 | ret.push(macro unityengine.GUILayout.MinHeight($v{minHeight}));
631 | if (maxHeight != null)
632 | ret.push(macro unityengine.GUILayout.MaxHeight($v{maxHeight}));
633 | if (minWidth != null)
634 | ret.push(macro unityengine.GUILayout.MinWidth($v{minWidth}));
635 | if (maxWidth != null)
636 | ret.push(macro unityengine.GUILayout.MaxWidth($v{maxWidth}));
637 | if (height != null)
638 | ret.push(macro unityengine.GUILayout.Height($v{height}));
639 | if (expandWidth != null)
640 | ret.push(macro unityengine.GUILayout.ExpandWidth($v{expandWidth}));
641 | if (expandHeight != null)
642 | ret.push(macro unityengine.GUILayout.ExpandHeight($v{expandHeight}));
643 | if (width != null)
644 | ret.push(macro unityengine.GUILayout.Width($v{width}));
645 |
646 | return ret;
647 | }
648 |
649 | private static function parseFloat(str:String):Null
650 | {
651 | if (str == null)
652 | return null;
653 | var ret = Std.parseFloat(str);
654 | if (Math.isNaN(ret))
655 | return null;
656 | return ret;
657 | }
658 |
659 | private static function parseBool(str:String):Null
660 | {
661 | return switch str {
662 | case null:
663 | null;
664 | case 'YES' | 'yes' | 'true':
665 | true;
666 | case 'NO' | 'no' | 'false':
667 | false;
668 | case _:
669 | null;
670 | }
671 | }
672 |
673 | private static function parseRect(str:String):Null
674 | {
675 | if (str == null)
676 | return null;
677 | var arr = str.trim().split(',').map(Std.parseFloat);
678 | return macro new unityengine.Rect($v{arr[0]},$v{arr[1]},$v{arr[2]},$v{arr[3]});
679 | }
680 |
681 | private static function parseColor(str:String):Null
682 | {
683 | if (str == null)
684 | return null;
685 |
686 | var rgba = switch str.trim() {
687 | case 'black':
688 | 0x000000ff;
689 | case 'blue':
690 | 0x0000ffff;
691 | case 'clear':
692 | 0x0;
693 | case 'cyan':
694 | 0x00FFFFFF;
695 | case 'gray':
696 | 0x808080ff;
697 | case 'magenta':
698 | 0xff00ffff;
699 | case 'red':
700 | 0xff0000ff;
701 | case 'white':
702 | 0xffffffff;
703 | case 'yellow':
704 | 0xffea04ff;
705 | case s if (s.charCodeAt(0) == '#'.code):
706 | s = s.substr(1);
707 | switch s.length {
708 | case 3:
709 | Std.parseInt('0x' + s.charAt(0) + s.charAt(0) + s.charAt(1) + s.charAt(1) + s.charAt(2) + s.charAt(2) + 'ff');
710 | case 4:
711 | Std.parseInt('0x' + s.charAt(0) + s.charAt(0) + s.charAt(1) + s.charAt(1) + s.charAt(2) + s.charAt(2) + s.charAt(3) + s.charAt(3));
712 | case 6:
713 | Std.parseInt('0x' + s + "ff");
714 | case 8:
715 | Std.parseInt('0x' + s);
716 | default:
717 | return null;
718 | }
719 | case _:
720 | return null;
721 | }
722 | var r = (rgba >>> 24) & 0xFF,
723 | g = (rgba >>> 16) & 0xFF,
724 | b = (rgba >>> 8) & 0xFF,
725 | a = rgba & 0xff;
726 | return macro new unityengine.Color($v{r / 0xff}, $v{g / 0xff}, $v{b / 0xff}, $v{a / 0xff});
727 | }
728 |
729 | private static function parseComments(c:String):Array<{ tag:Null, contents:String }>
730 | {
731 | var ret = [];
732 | var curTag = null;
733 | var txt = new StringBuf();
734 | for (ln in c.split("\n"))
735 | {
736 | var i = 0, len = ln.length;
737 | while (i < len)
738 | {
739 | switch(ln.fastCodeAt(i))
740 | {
741 | case ' '.code, '\t'.code, '*'.code: i++;
742 | case '@'.code: //found a tag
743 | var t = txt.toString();
744 | txt = new StringBuf();
745 | if (curTag != null || t.length > 0)
746 | {
747 | ret.push({ tag:curTag, contents:t });
748 | }
749 | var begin = ++i;
750 | while(i < len)
751 | {
752 | switch(ln.fastCodeAt(i))
753 | {
754 | case ' '.code, '\t'.code:
755 | break;
756 | default: i++;
757 | }
758 | }
759 | curTag = ln.substr(begin, i - begin);
760 | break;
761 | default: break;
762 | }
763 | }
764 | if (i < len)
765 | {
766 | txt.add(ln.substr(i).replace("\r", "").trim());
767 | txt.addChar(' '.code);
768 | }
769 | txt.addChar('\n'.code);
770 | }
771 |
772 | var t = txt.toString().trim();
773 | if (curTag != null || t.length > 0)
774 | ret.push({ tag:curTag, contents: t });
775 |
776 | return ret;
777 | }
778 |
779 | private static function toSep(s:String,sep:Int):String
780 | {
781 | if (s.length <= 1) return s; //allow upper-case aliases
782 | var buf = new StringBuf();
783 | var first = true;
784 | for (i in 0...s.length)
785 | {
786 | var chr = s.charCodeAt(i);
787 | if (chr >= 'A'.code && chr <= 'Z'.code)
788 | {
789 | if (!first)
790 | buf.addChar(sep);
791 | buf.addChar( chr - ('A'.code - 'a'.code) );
792 | first = true;
793 | } else {
794 | buf.addChar(chr);
795 | first = false;
796 | }
797 | }
798 |
799 | return buf.toString();
800 | }
801 | #end
802 | }
803 |
--------------------------------------------------------------------------------
/unihx/inspector/ObjectField.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | //@allow-scene-objects
4 | typedef ObjectField = T;
5 |
--------------------------------------------------------------------------------
/unihx/inspector/Password.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | typedef Password = String;
4 |
--------------------------------------------------------------------------------
/unihx/inspector/Range.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | //@upper @lower / @min @max
4 | //MinMax
5 | /**
6 | A special slider the user can use to specify a range between a min and a max.
7 | **/
8 | @:struct class Range
9 | {
10 | public var minLimit:Single;
11 | public var maxLimit:Single;
12 | public var minValue:Single;
13 | public var maxValue:Single;
14 |
15 | public function new(minLimit,maxLimit, ?minValue,?maxValue)
16 | {
17 | this.minLimit = minLimit;
18 | this.maxLimit = maxLimit;
19 | this.minValue = minValue == null ? minLimit : minValue;
20 | this.maxValue == null ? maxLimit : maxValue;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/unihx/inspector/Rect.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | typedef Rect = unityengine.Rect;
4 |
--------------------------------------------------------------------------------
/unihx/inspector/Select.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 | import cs.NativeArray;
3 |
4 | /**
5 | A generic popup selection field.
6 | **/
7 | @:struct @:nativeGen class Select
8 | {
9 | public var options:NativeArray;
10 | public var values:NativeArray;
11 | public var selectedIndex:Int;
12 |
13 | public var selected(get,never):Null;
14 |
15 | public function new(options:Array,values:Array,selected=-1)
16 | {
17 | this.options = cs.Lib.nativeArray(options,true);
18 | this.values = cs.Lib.nativeArray(values,true);
19 | this.selectedIndex = selected;
20 | }
21 |
22 | public static function fromOptions(options:Array,selected=-1):Select
23 | {
24 | return new Select(options,options,selected);
25 | }
26 |
27 | public static function fromMap(map:Map,?selected:String)
28 | {
29 | var arr = [ for (key in map.keys()) key ],
30 | vals = [ for (k in arr) map[k] ];
31 | var sel = if (selected == null)
32 | -1;
33 | else
34 | arr.indexOf(selected);
35 | return new Select(arr,vals,sel);
36 | }
37 |
38 | private function get_selected():Null
39 | {
40 | return selectedIndex < 0 ? null : values[selectedIndex];
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/unihx/inspector/Slider.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | /**
4 | A special slider the user can use to specify a value between a min and a max.
5 | **/
6 | @:nativeGen @:struct class Slider
7 | {
8 | public var minLimit:T;
9 | public var maxLimit:T;
10 | public var value:T;
11 |
12 | public function new(min,max,?value)
13 | {
14 | this.minLimit = min;
15 | this.maxLimit = max;
16 | this.value = value == null ? minLimit : value;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/unihx/inspector/Space.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | typedef Space = Void; // will be removed from the builded class
4 |
--------------------------------------------------------------------------------
/unihx/inspector/Tag.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | typedef Tag = String;
4 |
--------------------------------------------------------------------------------
/unihx/inspector/TextArea.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | typedef TextArea = String;
4 |
--------------------------------------------------------------------------------
/unihx/inspector/Vector2.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | typedef Vector2 = unityengine.Vector2;
4 |
--------------------------------------------------------------------------------
/unihx/inspector/Vector3.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | typedef Vector3 = unityengine.Vector3;
4 |
--------------------------------------------------------------------------------
/unihx/inspector/Vector4.hx:
--------------------------------------------------------------------------------
1 | package unihx.inspector;
2 |
3 | typedef Vector4 = unityengine.Vector4;
4 |
--------------------------------------------------------------------------------
/unityengine/Bounds.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | private typedef Data =
4 | #if macro
5 | Void
6 | #else
7 | BoundsData
8 | #end;
9 |
10 | @:forward abstract Bounds(Data) from Data to Data
11 | {
12 | #if !macro
13 | @:extern inline public function new(center:Vector3,size:Vector3)
14 | {
15 | this = new BoundsData(center,size);
16 | }
17 | @:extern inline public static function fromData(data:BoundsData):Bounds
18 | {
19 | return data;
20 | }
21 | #end
22 |
23 | macro public function with(ethis:haxe.macro.Expr, obj:haxe.macro.Expr):haxe.macro.Expr
24 | {
25 | return unihx._internal.StructHelper.with(['center','size'], macro : unityengine.Bounds, ethis, obj);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/unityengine/BoundsData.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:final @:csNative @:native("UnityEngine.Bounds") extern class BoundsData extends cs.system.ValueType
4 | {
5 | var center(get,set) : Vector3;
6 | var extents(get,set) : Vector3;
7 | var max(get,set) : Vector3;
8 | var min(get,set) : Vector3;
9 | var size(get,set) : Vector3;
10 | @:final @:overload function new(center : Vector3, size : Vector3) : Void;
11 | @:final @:overload function Contains(point : Vector3) : Bool;
12 | @:final @:overload function Encapsulate(point : Vector3) : Void;
13 | @:final @:overload function Encapsulate(bounds : Bounds) : Void;
14 | @:final @:overload function Expand(amount : Single) : Void;
15 | @:final @:overload function Expand(amount : Vector3) : Void;
16 | @:final @:overload function IntersectRay(ray : Ray) : Bool;
17 | @:final @:overload function IntersectRay(ray : Ray, distance : cs.Ref) : Bool;
18 | @:final @:overload function Intersects(bounds : Bounds) : Bool;
19 | @:final @:overload function SetMinMax(min : Vector3, max : Vector3) : Void;
20 | @:final @:overload function SqrDistance(point : Vector3) : Single;
21 | @:final @:overload private function get_center() : Vector3;
22 | @:final @:overload private function get_extents() : Vector3;
23 | @:final @:overload private function get_max() : Vector3;
24 | @:final @:overload private function get_min() : Vector3;
25 | @:final @:overload private function get_size() : Vector3;
26 | @:final @:overload private function set_center(value : Vector3) : Vector3;
27 | @:final @:overload private function set_extents(value : Vector3) : Vector3;
28 | @:final @:overload private function set_max(value : Vector3) : Vector3;
29 | @:final @:overload private function set_min(value : Vector3) : Vector3;
30 | @:final @:overload private function set_size(value : Vector3) : Vector3;
31 | @:final @:overload static function op_Equality(lhs : Bounds, rhs : Bounds) : Bool;
32 | @:final @:overload static function op_Inequality(lhs : Bounds, rhs : Bounds) : Bool;
33 | }
34 |
--------------------------------------------------------------------------------
/unityengine/Color.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:forward abstract Color(Data) from Data to Data
4 | {
5 | #if !macro
6 | @:extern inline public function new(r:Single,g:Single,b:Single,a:Single=1.0)
7 | {
8 | this = new Data(r,g,b,a);
9 | }
10 |
11 | @:extern inline public static function fromData(data:Data):Color
12 | {
13 | return data;
14 | }
15 |
16 | @:op(A+B) @:extern inline public static function add(a:Color, b:Color):Color
17 | {
18 | return Data.op_Addition(a,b);
19 | }
20 |
21 | @:op(A/B) @:extern inline public static function div(a:Color, b:Single):Color
22 | {
23 | return Data.op_Division(a,b);
24 | }
25 |
26 | @:from @:extern inline public static function fromVec4(vec:Vector4):Color
27 | {
28 | return new Color(vec.x, vec.y, vec.z, vec.w);
29 | }
30 |
31 | @:to @:extern inline public function toVec4():Vector4
32 | {
33 | return new Vector4(this.r, this.g, this.b, this.a);
34 | }
35 |
36 | @:op(A*B) @:extern inline public static function mul(a:Color, b:Color):Color
37 | {
38 | return Data.op_Multiply(a,b);
39 | }
40 |
41 | @:op(A*B) @:extern @:commutative inline public static function mulSingle(a:Color, b:Single):Color
42 | {
43 | return Data.op_Multiply(a,b);
44 | }
45 |
46 | @:op(A-B) @:extern inline public static function sub(a:Color, b:Color):Color
47 | {
48 | return Data.op_Subtraction(a,b);
49 | }
50 |
51 | @:arrayAccess @:extern inline public function get_Item(index:Int):Single
52 | {
53 | return this.get_Item(index);
54 | }
55 |
56 | @:arrayAccess @:extern inline public function set_Item(index:Int, val:Single):Single
57 | {
58 | this.set_Item(index,val);
59 | return val;
60 | }
61 | #end
62 |
63 | macro public function with(ethis:haxe.macro.Expr, obj:haxe.macro.Expr):haxe.macro.Expr
64 | {
65 | return unihx._internal.StructHelper.with(['r','g','b','a'], macro : unityengine.Color, ethis, obj);
66 | }
67 | }
68 |
69 | private typedef Data =
70 | #if macro
71 | Void
72 | #else
73 | ColorData
74 | #end;
75 |
76 |
--------------------------------------------------------------------------------
/unityengine/Color32.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 | import cs.StdTypes;
3 |
4 | @:forward abstract Color32(Data) from Data to Data
5 | {
6 | #if !macro
7 | @:extern inline public function new(r:UInt8,g:UInt8,b:UInt8,a:UInt8=0xff)
8 | {
9 | this = new Data(r,g,b,a);
10 | }
11 |
12 | @:extern inline public static function fromData(data:Data):Color32
13 | {
14 | return data;
15 | }
16 |
17 | @:from @:extern inline public static function fromColor(c:Color):Color32
18 | {
19 | return new Color32(Std.int(c.r * 0xff), Std.int(c.g * 0xff), Std.int(c.b * 0xff), Std.int(c.a * 0xff));
20 | }
21 |
22 | @:to @:extern inline public function toColor():Color
23 | {
24 | return new Color(this.r / 0xff, this.g / 0xff, this.b / 0xff, this.a / 0xff);
25 | }
26 | #end
27 |
28 | macro public function with(ethis:haxe.macro.Expr, obj:haxe.macro.Expr):haxe.macro.Expr
29 | {
30 | return unihx._internal.StructHelper.with(['r','g','b','a'], macro : unityengine.Color32, ethis, obj);
31 | }
32 | }
33 |
34 | private typedef Data =
35 | #if macro
36 | Void
37 | #else
38 | Color32Data
39 | #end;
40 |
41 |
42 |
--------------------------------------------------------------------------------
/unityengine/Color32Data.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:final @:csNative @:native("UnityEngine.Color32") extern class Color32Data extends cs.system.ValueType
4 | {
5 | var a : cs.types.UInt8;
6 | var b : cs.types.UInt8;
7 | var g : cs.types.UInt8;
8 | var r : cs.types.UInt8;
9 | @:final @:overload function new(r : cs.types.UInt8, g : cs.types.UInt8, b : cs.types.UInt8, a : cs.types.UInt8) : Void;
10 | @:final @:overload static function Lerp(a : Color32, b : Color32, t : Single) : Color32;
11 | @:final @:overload static function op_Implicit(c : Color) : Color32;
12 | @:final @:overload static function op_Implicit(c : Color32) : Color;
13 | }
14 |
--------------------------------------------------------------------------------
/unityengine/ColorData.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:final @:csNative @:native("UnityEngine.Color") extern class ColorData extends cs.system.ValueType
4 | {
5 | var a : Single;
6 | var b : Single;
7 | var g : Single;
8 | var gamma(get,never) : Color;
9 | var grayscale(get,never) : Single;
10 | var linear(get,never) : Color;
11 | var r : Single;
12 | @:final @:overload function new(r : Single, g : Single, b : Single, a : Single) : Void;
13 | @:final @:overload function new(r : Single, g : Single, b : Single) : Void;
14 | @:final @:overload function get_Item(index : Int) : Single;
15 | @:final @:overload private function get_gamma() : Color;
16 | @:final @:overload private function get_grayscale() : Single;
17 | @:final @:overload private function get_linear() : Color;
18 | @:final @:overload function set_Item(index : Int, value : Single) : Void;
19 | static var black(get,never) : Color;
20 | static var blue(get,never) : Color;
21 | static var clear(get,never) : Color;
22 | static var cyan(get,never) : Color;
23 | static var gray(get,never) : Color;
24 | static var green(get,never) : Color;
25 | static var grey(get,never) : Color;
26 | static var magenta(get,never) : Color;
27 | static var red(get,never) : Color;
28 | static var white(get,never) : Color;
29 | static var yellow(get,never) : Color;
30 | @:final @:overload static function Lerp(a : Color, b : Color, t : Single) : Color;
31 | @:final @:overload static private function get_black() : Color;
32 | @:final @:overload static private function get_blue() : Color;
33 | @:final @:overload static private function get_clear() : Color;
34 | @:final @:overload static private function get_cyan() : Color;
35 | @:final @:overload static private function get_gray() : Color;
36 | @:final @:overload static private function get_green() : Color;
37 | @:final @:overload static private function get_grey() : Color;
38 | @:final @:overload static private function get_magenta() : Color;
39 | @:final @:overload static private function get_red() : Color;
40 | @:final @:overload static private function get_white() : Color;
41 | @:final @:overload static private function get_yellow() : Color;
42 | @:final @:overload static function op_Addition(a : Color, b : Color) : Color;
43 | @:final @:overload static function op_Division(a : Color, b : Single) : Color;
44 | @:final @:overload static function op_Equality(lhs : Color, rhs : Color) : Bool;
45 | @:final @:overload static function op_Implicit(c : Color) : Vector4;
46 | @:final @:overload static function op_Implicit(v : Vector4) : Color;
47 | @:final @:overload static function op_Inequality(lhs : Color, rhs : Color) : Bool;
48 | @:final @:overload static function op_Multiply(a : Color, b : Color) : Color;
49 | @:final @:overload static function op_Multiply(b : Single, a : Color) : Color;
50 | @:final @:overload static function op_Multiply(a : Color, b : Single) : Color;
51 | @:final @:overload static function op_Subtraction(a : Color, b : Color) : Color;
52 | }
53 |
--------------------------------------------------------------------------------
/unityengine/HaxeBehaviour.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:nativeChildren class HaxeBehaviour extends MonoBehaviour
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/unityengine/Matrix4x4.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:forward abstract Matrix4x4(Data) from Data to Data
4 | {
5 | #if !macro
6 | @:extern inline public static function fromData(data:Data):Matrix4x4
7 | {
8 | return data;
9 | }
10 |
11 | @:op(A*B) @:extern inline public static function mul(a:Matrix4x4, b:Matrix4x4):Matrix4x4
12 | {
13 | return Data.op_Multiply(a,b);
14 | }
15 |
16 | @:op(A*B) @:extern @:commutative inline public static function mulVector(a:Matrix4x4, b:Vector4):Vector4
17 | {
18 | return Data.op_Multiply(a,b);
19 | }
20 |
21 | @:arrayAccess @:extern inline public function get_Item(index:Int):Single
22 | {
23 | return this.get_Item(index);
24 | }
25 |
26 | @:arrayAccess @:extern inline public function set_Item(index:Int, val:Single):Single
27 | {
28 | this.set_Item(index,val);
29 | return val;
30 | }
31 | #end
32 | }
33 |
34 | private typedef Data =
35 | #if macro
36 | Void
37 | #else
38 | Matrix4x4Data
39 | #end;
40 |
41 |
--------------------------------------------------------------------------------
/unityengine/Matrix4x4Data.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:final @:csNative @:native("UnityEngine.Matrix4x4") extern class Matrix4x4Data extends cs.system.ValueType
4 | {
5 | var inverse(get,never) : Matrix4x4;
6 | var isIdentity(get,never) : Bool;
7 | var m00 : Single;
8 | var m01 : Single;
9 | var m02 : Single;
10 | var m03 : Single;
11 | var m10 : Single;
12 | var m11 : Single;
13 | var m12 : Single;
14 | var m13 : Single;
15 | var m20 : Single;
16 | var m21 : Single;
17 | var m22 : Single;
18 | var m23 : Single;
19 | var m30 : Single;
20 | var m31 : Single;
21 | var m32 : Single;
22 | var m33 : Single;
23 | var transpose(get,never) : Matrix4x4;
24 | @:final @:overload function GetColumn(i : Int) : Vector4;
25 | @:final @:overload function GetRow(i : Int) : Vector4;
26 | @:final @:overload function MultiplyPoint(v : Vector3) : Vector3;
27 | @:final @:overload function MultiplyPoint3x4(v : Vector3) : Vector3;
28 | @:final @:overload function MultiplyVector(v : Vector3) : Vector3;
29 | @:final @:overload function SetColumn(i : Int, v : Vector4) : Void;
30 | @:final @:overload function SetRow(i : Int, v : Vector4) : Void;
31 | @:final @:overload function SetTRS(pos : Vector3, q : Quaternion, s : Vector3) : Void;
32 | @:final @:overload function get_Item(row : Int, column : Int) : Single;
33 | @:final @:overload function get_Item(index : Int) : Single;
34 | @:final @:overload private function get_inverse() : Matrix4x4;
35 | @:final @:overload private function get_isIdentity() : Bool;
36 | @:final @:overload private function get_transpose() : Matrix4x4;
37 | @:final @:overload function set_Item(index : Int, value : Single) : Void;
38 | @:final @:overload function set_Item(row : Int, column : Int, value : Single) : Void;
39 | static var identity(get,never) : Matrix4x4;
40 | static var zero(get,never) : Matrix4x4;
41 | @:final @:overload static function Inverse(m : Matrix4x4) : Matrix4x4;
42 | @:final @:overload static function Ortho(left : Single, right : Single, bottom : Single, top : Single, zNear : Single, zFar : Single) : Matrix4x4;
43 | @:final @:overload static function Perspective(fov : Single, aspect : Single, zNear : Single, zFar : Single) : Matrix4x4;
44 | @:final @:overload static function Scale(v : Vector3) : Matrix4x4;
45 | @:final @:overload static function TRS(pos : Vector3, q : Quaternion, s : Vector3) : Matrix4x4;
46 | @:final @:overload static function Transpose(m : Matrix4x4) : Matrix4x4;
47 | @:final @:overload static private function get_identity() : Matrix4x4;
48 | @:final @:overload static private function get_zero() : Matrix4x4;
49 | @:final @:overload static function op_Equality(lhs : Matrix4x4, rhs : Matrix4x4) : Bool;
50 | @:final @:overload static function op_Inequality(lhs : Matrix4x4, rhs : Matrix4x4) : Bool;
51 | @:final @:overload static function op_Multiply(lhs : Matrix4x4, rhs : Matrix4x4) : Matrix4x4;
52 | @:final @:overload static function op_Multiply(lhs : Matrix4x4, v : Vector4) : Vector4;
53 | }
54 |
--------------------------------------------------------------------------------
/unityengine/Quaternion.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:forward abstract Quaternion(Data) from Data to Data
4 | {
5 | #if !macro
6 | @:extern inline public function new(x:Single,y:Single,z:Single,w:Single)
7 | {
8 | this = new Data(x,y,z,w);
9 | }
10 |
11 | @:extern inline public static function fromData(data:Data):Quaternion
12 | {
13 | return data;
14 | }
15 |
16 | @:op(A*B) @:extern inline public static function mul(a:Quaternion, b:Quaternion):Quaternion
17 | {
18 | return Data.op_Multiply(a,b);
19 | }
20 |
21 | @:op(A*B) @:extern inline public function rotate(point:Vector3):Vector3
22 | {
23 | return Data.op_Multiply(this,point);
24 | }
25 |
26 | @:arrayAccess @:extern inline public function get_Item(index:Int):Single
27 | {
28 | return this.get_Item(index);
29 | }
30 |
31 | @:arrayAccess @:extern inline public function set_Item(index:Int, val:Single):Single
32 | {
33 | this.set_Item(index,val);
34 | return val;
35 | }
36 | #end
37 |
38 | macro public function with(ethis:haxe.macro.Expr, obj:haxe.macro.Expr):haxe.macro.Expr
39 | {
40 | return unihx._internal.StructHelper.with(['x','y','z','w'], macro : unityengine.Quaternion, ethis, obj);
41 | }
42 | }
43 |
44 | private typedef Data =
45 | #if macro
46 | Void
47 | #else
48 | QuaternionData
49 | #end;
50 |
51 |
--------------------------------------------------------------------------------
/unityengine/QuaternionData.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:final @:csNative @:native("UnityEngine.Quaternion") extern class QuaternionData extends cs.system.ValueType
4 | {
5 | var eulerAngles(get,set) : Vector3;
6 | var w : Single;
7 | var x : Single;
8 | var y : Single;
9 | var z : Single;
10 | @:final @:overload function new(x : Single, y : Single, z : Single, w : Single) : Void;
11 | @:final @:overload function Set(new_x : Single, new_y : Single, new_z : Single, new_w : Single) : Void;
12 | @:final @:overload function SetAxisAngle(axis : Vector3, angle : Single) : Void;
13 | @:final @:overload function SetEulerAngles(x : Single, y : Single, z : Single) : Void;
14 | @:final @:overload function SetEulerAngles(euler : Vector3) : Void;
15 | @:final @:overload function SetEulerRotation(x : Single, y : Single, z : Single) : Void;
16 | @:final @:overload function SetEulerRotation(euler : Vector3) : Void;
17 | @:final @:overload function SetFromToRotation(fromDirection : Vector3, toDirection : Vector3) : Void;
18 | @:final @:overload function SetLookRotation(view : Vector3) : Void;
19 | @:final @:overload function SetLookRotation(view : Vector3, up : Vector3) : Void;
20 | @:final @:overload function ToAngleAxis(angle : cs.Ref, axis : cs.Ref) : Void;
21 | @:final @:overload function ToAxisAngle(axis : cs.Ref, angle : cs.Ref) : Void;
22 | @:final @:overload function ToEuler() : Vector3;
23 | @:final @:overload function ToEulerAngles() : Vector3;
24 | @:final @:overload function get_Item(index : Int) : Single;
25 | @:final @:overload private function get_eulerAngles() : Vector3;
26 | @:final @:overload function set_Item(index : Int, value : Single) : Void;
27 | @:final @:overload private function set_eulerAngles(value : Vector3) : Vector3;
28 | static var identity(get,never) : Quaternion;
29 | static var kEpsilon(default,never) : Single;
30 | @:final @:overload static function Angle(a : Quaternion, b : Quaternion) : Single;
31 | @:final @:overload static function AngleAxis(angle : Single, axis : Vector3) : Quaternion;
32 | @:final @:overload static function AxisAngle(axis : Vector3, angle : Single) : Quaternion;
33 | @:final @:overload static function Dot(a : Quaternion, b : Quaternion) : Single;
34 | @:final @:overload static function Euler(x : Single, y : Single, z : Single) : Quaternion;
35 | @:final @:overload static function Euler(euler : Vector3) : Quaternion;
36 | @:final @:overload static function EulerAngles(x : Single, y : Single, z : Single) : Quaternion;
37 | @:final @:overload static function EulerAngles(euler : Vector3) : Quaternion;
38 | @:final @:overload static function EulerRotation(x : Single, y : Single, z : Single) : Quaternion;
39 | @:final @:overload static function EulerRotation(euler : Vector3) : Quaternion;
40 | @:final @:overload static function FromToRotation(fromDirection : Vector3, toDirection : Vector3) : Quaternion;
41 | @:final @:overload static function Inverse(rotation : Quaternion) : Quaternion;
42 | @:final @:overload static function Lerp(from : Quaternion, to : Quaternion, t : Single) : Quaternion;
43 | @:final @:overload static function LookRotation(forward : Vector3, upwards : Vector3) : Quaternion;
44 | @:final @:overload static function LookRotation(forward : Vector3) : Quaternion;
45 | @:final @:overload static function RotateTowards(from : Quaternion, to : Quaternion, maxDegreesDelta : Single) : Quaternion;
46 | @:final @:overload static function Slerp(from : Quaternion, to : Quaternion, t : Single) : Quaternion;
47 | @:native("ToEulerAngles") @:final @:overload static function _ToEulerAngles(rotation : Quaternion) : Vector3;
48 | @:final @:overload static private function get_identity() : Quaternion;
49 | @:final @:overload static function op_Equality(lhs : Quaternion, rhs : Quaternion) : Bool;
50 | @:final @:overload static function op_Inequality(lhs : Quaternion, rhs : Quaternion) : Bool;
51 | @:final @:overload static function op_Multiply(lhs : Quaternion, rhs : Quaternion) : Quaternion;
52 | @:final @:overload static function op_Multiply(rotation : Quaternion, point : Vector3) : Vector3;
53 | }
54 |
--------------------------------------------------------------------------------
/unityengine/Rect.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:forward abstract Rect(Data) from Data to Data
4 | {
5 | #if !macro
6 | @:extern inline public function new(left:Single,top:Single,width:Single,height:Single)
7 | {
8 | this = new Data(left,top,width,height);
9 | }
10 |
11 | @:extern inline public static function fromData(data:Data):Rect
12 | {
13 | return data;
14 | }
15 |
16 | #end
17 |
18 | macro public function with(ethis:haxe.macro.Expr, obj:haxe.macro.Expr):haxe.macro.Expr
19 | {
20 | return unihx._internal.StructHelper.with(['left','top','width','height'], macro : unityengine.Rect, ethis, obj);
21 | }
22 | }
23 |
24 | private typedef Data =
25 | #if macro
26 | Void
27 | #else
28 | RectData
29 | #end;
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/unityengine/RectData.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:final @:csNative @:native("UnityEngine.Rect") extern class RectData extends cs.system.ValueType
4 | {
5 | var bottom(get,never) : Single;
6 | var center(get,set) : Vector2;
7 | var height(get,set) : Single;
8 | var left(get,never) : Single;
9 | var right(get,never) : Single;
10 | var top(get,never) : Single;
11 | var width(get,set) : Single;
12 | var x(get,set) : Single;
13 | var xMax(get,set) : Single;
14 | var xMin(get,set) : Single;
15 | var y(get,set) : Single;
16 | var yMax(get,set) : Single;
17 | var yMin(get,set) : Single;
18 | @:final @:overload function new(left : Single, top : Single, width : Single, height : Single) : Void;
19 | @:final @:overload function new(source : Rect) : Void;
20 | @:final @:overload function Contains(point : Vector2) : Bool;
21 | @:final @:overload function Contains(point : Vector3, allowInverse : Bool) : Bool;
22 | @:final @:overload function Contains(point : Vector3) : Bool;
23 | @:final @:overload function Overlaps(other : Rect) : Bool;
24 | @:final @:overload function Overlaps(other : Rect, allowInverse : Bool) : Bool;
25 | @:final @:overload function Set(left : Single, top : Single, width : Single, height : Single) : Void;
26 | @:final @:overload private function get_bottom() : Single;
27 | @:final @:overload private function get_center() : Vector2;
28 | @:final @:overload private function get_height() : Single;
29 | @:final @:overload private function get_left() : Single;
30 | @:final @:overload private function get_right() : Single;
31 | @:final @:overload private function get_top() : Single;
32 | @:final @:overload private function get_width() : Single;
33 | @:final @:overload private function get_x() : Single;
34 | @:final @:overload private function get_xMax() : Single;
35 | @:final @:overload private function get_xMin() : Single;
36 | @:final @:overload private function get_y() : Single;
37 | @:final @:overload private function get_yMax() : Single;
38 | @:final @:overload private function get_yMin() : Single;
39 | @:final @:overload private function set_center(value : Vector2) : Vector2;
40 | @:final @:overload private function set_height(value : Single) : Single;
41 | @:final @:overload private function set_width(value : Single) : Single;
42 | @:final @:overload private function set_x(value : Single) : Single;
43 | @:final @:overload private function set_xMax(value : Single) : Single;
44 | @:final @:overload private function set_xMin(value : Single) : Single;
45 | @:final @:overload private function set_y(value : Single) : Single;
46 | @:final @:overload private function set_yMax(value : Single) : Single;
47 | @:final @:overload private function set_yMin(value : Single) : Single;
48 | @:final @:overload static function MinMaxRect(left : Single, top : Single, right : Single, bottom : Single) : Rect;
49 | @:final @:overload static function op_Equality(lhs : Rect, rhs : Rect) : Bool;
50 | @:final @:overload static function op_Inequality(lhs : Rect, rhs : Rect) : Bool;
51 | }
52 |
--------------------------------------------------------------------------------
/unityengine/Vector2.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:forward abstract Vector2(Data) from Data to Data
4 | {
5 | #if !macro
6 | @:extern inline public function new(x:Single=.0,y:Single=.0)
7 | {
8 | this = new Data(x,y);
9 | }
10 |
11 | @:extern inline public static function fromData(data:Data):Vector2
12 | {
13 | return data;
14 | }
15 |
16 | @:op(A+B) @:extern inline public static function add(a:Vector2, b:Vector2):Vector2
17 | {
18 | return Data.op_Addition(a,b);
19 | }
20 |
21 | @:op(A/B) @:extern inline public static function div(a:Vector2, b:Single):Vector2
22 | {
23 | return Data.op_Division(a,b);
24 | }
25 |
26 | @:to @:extern inline public function toVec3():Vector3
27 | {
28 | return new Vector3(this.x,this.y);
29 | }
30 |
31 | @:to @:extern inline public function toVec4():Vector4
32 | {
33 | return new Vector4(this.x,this.y);
34 | }
35 |
36 | @:op(A*B) @:extern @:commutative inline public static function mul(a:Vector2, b:Single):Vector2
37 | {
38 | return Data.op_Multiply(a,b);
39 | }
40 |
41 | @:op(A-B) @:extern inline public static function sub(a:Vector2, b:Vector2):Vector2
42 | {
43 | return Data.op_Subtraction(a,b);
44 | }
45 |
46 | @:op(-A) @:extern inline public function negate():Vector2
47 | {
48 | return Data.op_UnaryNegation(this);
49 | }
50 |
51 | @:arrayAccess @:extern inline public function get_Item(index:Int):Single
52 | {
53 | return this.get_Item(index);
54 | }
55 |
56 | @:arrayAccess @:extern inline public function set_Item(index:Int, val:Single):Single
57 | {
58 | this.set_Item(index,val);
59 | return val;
60 | }
61 | #end
62 |
63 | macro public function with(ethis:haxe.macro.Expr, obj:haxe.macro.Expr):haxe.macro.Expr
64 | {
65 | return unihx._internal.StructHelper.with(['x','y'], macro : unityengine.Vector2, ethis, obj);
66 | }
67 |
68 | public static var kEpsilon(get,never) : Single;
69 | public static var one(get,never) : Vector2;
70 | public static var right(get,never) : Vector2;
71 | public static var up(get,never) : Vector2;
72 | public static var zero(get,never) : Vector2;
73 |
74 | inline static private function get_kEpsilon() : Single
75 | {
76 | return Data.kEpsilon;
77 | }
78 | inline static private function get_one() : Vector2
79 | {
80 | return Data.one;
81 | }
82 | inline static private function get_right() : Vector2
83 | {
84 | return Data.right;
85 | }
86 | inline static private function get_up() : Vector2
87 | {
88 | return Data.up;
89 | }
90 | inline static private function get_zero() : Vector2
91 | {
92 | return Data.zero;
93 | }
94 | }
95 |
96 | private typedef Data =
97 | #if macro
98 | Void
99 | #else
100 | Vector2Data
101 | #end;
102 |
--------------------------------------------------------------------------------
/unityengine/Vector2Data.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:final @:csNative @:native("UnityEngine.Vector2") extern class Vector2Data extends cs.system.ValueType
4 | {
5 | var magnitude(get,never) : Single;
6 | var normalized(get,never) : Vector2;
7 | var sqrMagnitude(get,never) : Single;
8 | var x : Single;
9 | var y : Single;
10 | @:final @:overload function new(x : Single, y : Single) : Void;
11 | @:final @:overload function Normalize() : Void;
12 | @:final @:overload function Scale(scale : Vector2) : Void;
13 | @:final @:overload function Set(new_x : Single, new_y : Single) : Void;
14 | @:final @:overload function SqrMagnitude() : Single;
15 | @:final @:overload function get_Item(index : Int) : Single;
16 | @:final @:overload private function get_magnitude() : Single;
17 | @:final @:overload private function get_normalized() : Vector2;
18 | @:final @:overload private function get_sqrMagnitude() : Single;
19 | @:final @:overload function set_Item(index : Int, value : Single) : Void;
20 | static var kEpsilon(default,never) : Single;
21 | static var one(get,never) : Vector2;
22 | static var right(get,never) : Vector2;
23 | static var up(get,never) : Vector2;
24 | static var zero(get,never) : Vector2;
25 | @:final @:overload static function Angle(from : Vector2, to : Vector2) : Single;
26 | @:final @:overload static function ClampMagnitude(vector : Vector2, maxLength : Single) : Vector2;
27 | @:final @:overload static function Distance(a : Vector2, b : Vector2) : Single;
28 | @:final @:overload static function Dot(lhs : Vector2, rhs : Vector2) : Single;
29 | @:final @:overload static function Lerp(from : Vector2, to : Vector2, t : Single) : Vector2;
30 | @:final @:overload static function Max(lhs : Vector2, rhs : Vector2) : Vector2;
31 | @:final @:overload static function Min(lhs : Vector2, rhs : Vector2) : Vector2;
32 | @:final @:overload static function MoveTowards(current : Vector2, target : Vector2, maxDistanceDelta : Single) : Vector2;
33 | @:native("Scale") @:final @:overload static function _Scale(a : Vector2, b : Vector2) : Vector2;
34 | @:native("SqrMagnitude") @:final @:overload static function _SqrMagnitude(a : Vector2) : Single;
35 | @:final @:overload static private function get_one() : Vector2;
36 | @:final @:overload static private function get_right() : Vector2;
37 | @:final @:overload static private function get_up() : Vector2;
38 | @:final @:overload static private function get_zero() : Vector2;
39 | @:final @:overload static function op_Addition(a : Vector2, b : Vector2) : Vector2;
40 | @:final @:overload static function op_Division(a : Vector2, d : Single) : Vector2;
41 | @:final @:overload static function op_Equality(lhs : Vector2, rhs : Vector2) : Bool;
42 | @:final @:overload static function op_Implicit(v : Vector3) : Vector2;
43 | @:final @:overload static function op_Implicit(v : Vector2) : Vector3;
44 | @:final @:overload static function op_Inequality(lhs : Vector2, rhs : Vector2) : Bool;
45 | @:final @:overload static function op_Multiply(a : Vector2, d : Single) : Vector2;
46 | @:final @:overload static function op_Multiply(d : Single, a : Vector2) : Vector2;
47 | @:final @:overload static function op_Subtraction(a : Vector2, b : Vector2) : Vector2;
48 | @:final @:overload static function op_UnaryNegation(a : Vector2) : Vector2;
49 | }
50 |
--------------------------------------------------------------------------------
/unityengine/Vector3.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:forward abstract Vector3(Data) from Data to Data
4 | {
5 | #if !macro
6 | @:extern inline public function new(x:Single=.0,y:Single=.0,z:Single=.0)
7 | {
8 | this = new Data(x,y,z);
9 | }
10 |
11 | @:extern inline public static function fromData(data:Data):Vector3
12 | {
13 | return data;
14 | }
15 |
16 | @:op(A+B) @:extern inline public static function add(a:Vector3, b:Vector3):Vector3
17 | {
18 | return Data.op_Addition(a,b);
19 | }
20 |
21 | @:op(A/B) @:extern inline public static function div(a:Vector3, b:Single):Vector3
22 | {
23 | return Data.op_Division(a,b);
24 | }
25 |
26 | @:from @:extern inline public static function fromVec2(v:Vector2):Vector3
27 | {
28 | return new Vector3(v.x,v.y,0);
29 | }
30 |
31 | @:to @:extern inline public function toVec2():Vector2
32 | {
33 | return new Vector2(this.x,this.y);
34 | }
35 |
36 | @:op(A*B) @:extern @:commutative inline public static function mul(a:Vector3, b:Single):Vector3
37 | {
38 | return Data.op_Multiply(a,b);
39 | }
40 |
41 | @:op(A-B) @:extern inline public static function sub(a:Vector3, b:Vector3):Vector3
42 | {
43 | return Data.op_Subtraction(a,b);
44 | }
45 |
46 | @:op(-A) @:extern inline public function negate():Vector3
47 | {
48 | return Data.op_UnaryNegation(this);
49 | }
50 |
51 | @:arrayAccess @:extern inline public function get_Item(index:Int):Single
52 | {
53 | return this.get_Item(index);
54 | }
55 |
56 | @:arrayAccess @:extern inline public function set_Item(index:Int, val:Single):Single
57 | {
58 | this.set_Item(index,val);
59 | return val;
60 | }
61 | #end
62 |
63 | macro public function with(ethis:haxe.macro.Expr, obj:haxe.macro.Expr):haxe.macro.Expr
64 | {
65 | return unihx._internal.StructHelper.with(['x','y','z'], macro : unityengine.Vector3, ethis, obj);
66 | }
67 | }
68 |
69 | private typedef Data =
70 | #if macro
71 | Void
72 | #else
73 | Vector3Data
74 | #end;
75 |
--------------------------------------------------------------------------------
/unityengine/Vector3Data.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:final @:csNative @:native("UnityEngine.Vector3") extern class Vector3Data extends cs.system.ValueType
4 | {
5 | var magnitude(get,never) : Single;
6 | var normalized(get,never) : Vector3;
7 | var sqrMagnitude(get,never) : Single;
8 | var x : Single;
9 | var y : Single;
10 | var z : Single;
11 | @:final @:overload function new(x : Single, y : Single, z : Single) : Void;
12 | @:final @:overload function new(x : Single, y : Single) : Void;
13 | @:final @:overload function Normalize() : Void;
14 | @:final @:overload function Scale(scale : Vector3) : Void;
15 | @:final @:overload function Set(new_x : Single, new_y : Single, new_z : Single) : Void;
16 | @:final @:overload function get_Item(index : Int) : Single;
17 | @:final @:overload private function get_magnitude() : Single;
18 | @:final @:overload private function get_normalized() : Vector3;
19 | @:final @:overload private function get_sqrMagnitude() : Single;
20 | @:final @:overload function set_Item(index : Int, value : Single) : Void;
21 | static var back(get,never) : Vector3;
22 | static var down(get,never) : Vector3;
23 | static var forward(get,never) : Vector3;
24 | static var fwd(get,never) : Vector3;
25 | static var kEpsilon(default,never) : Single;
26 | static var left(get,never) : Vector3;
27 | static var one(get,never) : Vector3;
28 | static var right(get,never) : Vector3;
29 | static var up(get,never) : Vector3;
30 | static var zero(get,never) : Vector3;
31 | @:final @:overload static function Angle(from : Vector3, to : Vector3) : Single;
32 | @:final @:overload static function AngleBetween(from : Vector3, to : Vector3) : Single;
33 | @:final @:overload static function ClampMagnitude(vector : Vector3, maxLength : Single) : Vector3;
34 | @:final @:overload static function Cross(lhs : Vector3, rhs : Vector3) : Vector3;
35 | @:final @:overload static function Distance(a : Vector3, b : Vector3) : Single;
36 | @:final @:overload static function Dot(lhs : Vector3, rhs : Vector3) : Single;
37 | @:final @:overload static function Exclude(excludeThis : Vector3, fromThat : Vector3) : Vector3;
38 | @:final @:overload static function Lerp(from : Vector3, to : Vector3, t : Single) : Vector3;
39 | @:final @:overload static function Magnitude(a : Vector3) : Single;
40 | @:final @:overload static function Max(lhs : Vector3, rhs : Vector3) : Vector3;
41 | @:final @:overload static function Min(lhs : Vector3, rhs : Vector3) : Vector3;
42 | @:final @:overload static function MoveTowards(current : Vector3, target : Vector3, maxDistanceDelta : Single) : Vector3;
43 | @:final @:overload static function OrthoNormalize(normal : cs.Ref, tangent : cs.Ref) : Void;
44 | @:final @:overload static function OrthoNormalize(normal : cs.Ref, tangent : cs.Ref, binormal : cs.Ref) : Void;
45 | @:final @:overload static function Project(vector : Vector3, onNormal : Vector3) : Vector3;
46 | @:final @:overload static function Reflect(inDirection : Vector3, inNormal : Vector3) : Vector3;
47 | @:final @:overload static function RotateTowards(current : Vector3, target : Vector3, maxRadiansDelta : Single, maxMagnitudeDelta : Single) : Vector3;
48 | @:final @:overload static function Slerp(from : Vector3, to : Vector3, t : Single) : Vector3;
49 | @:final @:overload static function SmoothDamp(current : Vector3, target : Vector3, currentVelocity : cs.Ref, smoothTime : Single, maxSpeed : Single) : Vector3;
50 | @:final @:overload static function SmoothDamp(current : Vector3, target : Vector3, currentVelocity : cs.Ref, smoothTime : Single, maxSpeed : Single, deltaTime : Single) : Vector3;
51 | @:final @:overload static function SmoothDamp(current : Vector3, target : Vector3, currentVelocity : cs.Ref, smoothTime : Single) : Vector3;
52 | @:final @:overload static function SqrMagnitude(a : Vector3) : Single;
53 | @:native("Normalize") @:final @:overload static function _Normalize(value : Vector3) : Vector3;
54 | @:native("Scale") @:final @:overload static function _Scale(a : Vector3, b : Vector3) : Vector3;
55 | @:final @:overload static private function get_back() : Vector3;
56 | @:final @:overload static private function get_down() : Vector3;
57 | @:final @:overload static private function get_forward() : Vector3;
58 | @:final @:overload static private function get_fwd() : Vector3;
59 | @:final @:overload static private function get_left() : Vector3;
60 | @:final @:overload static private function get_one() : Vector3;
61 | @:final @:overload static private function get_right() : Vector3;
62 | @:final @:overload static private function get_up() : Vector3;
63 | @:final @:overload static private function get_zero() : Vector3;
64 | @:final @:overload static function op_Addition(a : Vector3, b : Vector3) : Vector3;
65 | @:final @:overload static function op_Division(a : Vector3, d : Single) : Vector3;
66 | @:final @:overload static function op_Equality(lhs : Vector3, rhs : Vector3) : Bool;
67 | @:final @:overload static function op_Inequality(lhs : Vector3, rhs : Vector3) : Bool;
68 | @:final @:overload static function op_Multiply(a : Vector3, d : Single) : Vector3;
69 | @:final @:overload static function op_Multiply(d : Single, a : Vector3) : Vector3;
70 | @:final @:overload static function op_Subtraction(a : Vector3, b : Vector3) : Vector3;
71 | @:final @:overload static function op_UnaryNegation(a : Vector3) : Vector3;
72 | }
73 |
--------------------------------------------------------------------------------
/unityengine/Vector4.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:forward abstract Vector4(Data) from Data to Data
4 | {
5 | #if !macro
6 | @:extern inline public function new(x:Single=.0,y:Single=.0,z:Single=.0,w:Single=0.)
7 | {
8 | this = new Data(x,y,z,w);
9 | }
10 |
11 | @:extern inline public static function fromData(data:Data):Vector4
12 | {
13 | return data;
14 | }
15 |
16 | @:op(A+B) @:extern inline public static function add(a:Vector4, b:Vector4):Vector4
17 | {
18 | return Data.op_Addition(a,b);
19 | }
20 |
21 | @:op(A/B) @:extern inline public static function div(a:Vector4, b:Single):Vector4
22 | {
23 | return Data.op_Division(a,b);
24 | }
25 |
26 | @:from @:extern inline public static function fromVec3(v:Vector3):Vector4
27 | {
28 | return new Vector4(v.x,v.y,v.z,0);
29 | }
30 |
31 | @:from @:extern inline public static function fromVec2(v:Vector2):Vector4
32 | {
33 | return new Vector4(v.x,v.y,0,0);
34 | }
35 |
36 | @:to @:extern inline public function toVec2():Vector2
37 | {
38 | return new Vector2(this.x,this.y);
39 | }
40 |
41 | @:op(A*B) @:extern @:commutative inline public static function mul(a:Vector4, b:Single):Vector4
42 | {
43 | return Data.op_Multiply(a,b);
44 | }
45 |
46 | @:op(A-B) @:extern inline public static function sub(a:Vector4, b:Vector4):Vector4
47 | {
48 | return Data.op_Subtraction(a,b);
49 | }
50 |
51 | @:op(-A) @:extern inline public function negate():Vector4
52 | {
53 | return Data.op_UnaryNegation(this);
54 | }
55 |
56 | @:arrayAccess @:extern inline public function get_Item(index:Int):Single
57 | {
58 | return this.get_Item(index);
59 | }
60 |
61 | @:arrayAccess @:extern inline public function set_Item(index:Int, val:Single):Single
62 | {
63 | this.set_Item(index,val);
64 | return val;
65 | }
66 | #end
67 |
68 | macro public function with(ethis:haxe.macro.Expr, obj:haxe.macro.Expr):haxe.macro.Expr
69 | {
70 | return unihx._internal.StructHelper.with(['x','y','z','w'], macro : unityengine.Vector4, ethis, obj);
71 | }
72 | }
73 |
74 | private typedef Data =
75 | #if macro
76 | Void
77 | #else
78 | Vector4Data
79 | #end;
80 |
--------------------------------------------------------------------------------
/unityengine/Vector4Data.hx:
--------------------------------------------------------------------------------
1 | package unityengine;
2 |
3 | @:final @:csNative @:native("UnityEngine.Vector4") extern class Vector4Data extends cs.system.ValueType
4 | {
5 | var magnitude(get,never) : Single;
6 | var normalized(get,never) : Vector4;
7 | var sqrMagnitude(get,never) : Single;
8 | var w : Single;
9 | var x : Single;
10 | var y : Single;
11 | var z : Single;
12 | @:final @:overload function new(x : Single, y : Single, z : Single, w : Single) : Void;
13 | @:final @:overload function new(x : Single, y : Single) : Void;
14 | @:final @:overload function new(x : Single, y : Single, z : Single) : Void;
15 | @:final @:overload function Normalize() : Void;
16 | @:final @:overload function Scale(scale : Vector4) : Void;
17 | @:final @:overload function Set(new_x : Single, new_y : Single, new_z : Single, new_w : Single) : Void;
18 | @:final @:overload function SqrMagnitude() : Single;
19 | @:final @:overload function get_Item(index : Int) : Single;
20 | @:final @:overload private function get_magnitude() : Single;
21 | @:final @:overload private function get_normalized() : Vector4;
22 | @:final @:overload private function get_sqrMagnitude() : Single;
23 | @:final @:overload function set_Item(index : Int, value : Single) : Void;
24 | static var kEpsilon(default,never) : Single;
25 | static var one(get,never) : Vector4;
26 | static var zero(get,never) : Vector4;
27 | @:final @:overload static function Distance(a : Vector4, b : Vector4) : Single;
28 | @:final @:overload static function Dot(a : Vector4, b : Vector4) : Single;
29 | @:final @:overload static function Lerp(from : Vector4, to : Vector4, t : Single) : Vector4;
30 | @:final @:overload static function Magnitude(a : Vector4) : Single;
31 | @:final @:overload static function Max(lhs : Vector4, rhs : Vector4) : Vector4;
32 | @:final @:overload static function Min(lhs : Vector4, rhs : Vector4) : Vector4;
33 | @:final @:overload static function MoveTowards(current : Vector4, target : Vector4, maxDistanceDelta : Single) : Vector4;
34 | @:final @:overload static function Project(a : Vector4, b : Vector4) : Vector4;
35 | @:native("Normalize") @:final @:overload static function _Normalize(a : Vector4) : Vector4;
36 | @:native("Scale") @:final @:overload static function _Scale(a : Vector4, b : Vector4) : Vector4;
37 | @:native("SqrMagnitude") @:final @:overload static function _SqrMagnitude(a : Vector4) : Single;
38 | @:final @:overload static private function get_one() : Vector4;
39 | @:final @:overload static private function get_zero() : Vector4;
40 | @:final @:overload static function op_Addition(a : Vector4, b : Vector4) : Vector4;
41 | @:final @:overload static function op_Division(a : Vector4, d : Single) : Vector4;
42 | @:final @:overload static function op_Equality(lhs : Vector4, rhs : Vector4) : Bool;
43 | @:final @:overload static function op_Implicit(v : Vector3) : Vector4;
44 | @:final @:overload static function op_Implicit(v : Vector4) : Vector2;
45 | @:final @:overload static function op_Implicit(v : Vector2) : Vector4;
46 | @:final @:overload static function op_Inequality(lhs : Vector4, rhs : Vector4) : Bool;
47 | @:final @:overload static function op_Multiply(a : Vector4, d : Single) : Vector4;
48 | @:final @:overload static function op_Multiply(d : Single, a : Vector4) : Vector4;
49 | @:final @:overload static function op_Subtraction(a : Vector4, b : Vector4) : Vector4;
50 | @:final @:overload static function op_UnaryNegation(a : Vector4) : Vector4;
51 | }
52 |
--------------------------------------------------------------------------------