diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 5218c52f7..dd88831dd 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,6 +1,6 @@ # These are supported funding model platforms -github: [jgranick] +github: [jgranick, joshtynjala] patreon: openfl open_collective: openfl ko_fi: # Replace with a single Ko-fi username diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b7e32db6e..286baeb53 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,9 +1,12 @@ name: CI on: [push, pull_request] +env: + HAXE_VERSION: 4.2.5 + jobs: - linux-ndll: + linux: runs-on: ubuntu-20.04 steps: @@ -18,7 +21,7 @@ jobs: - uses: krdlab/setup-haxe@v1 with: - haxe-version: 4.2.5 + haxe-version: ${{ env.HAXE_VERSION }} - name: Set HAXEPATH run: | @@ -36,7 +39,7 @@ jobs: - name: Rebuild Lime tools run: | - haxelib dev lime $GITHUB_WORKSPACE + haxelib dev lime ${{ github.workspace }} haxelib run lime rebuild tools -nocolor -verbose -nocffi haxelib run lime setup -alias -y -nocffi @@ -69,8 +72,27 @@ jobs: templates/bin/hl/Linux64 if-no-files-found: error - macos-ndll: - runs-on: macos-11 + - name: Install samples + run: | + haxelib git lime-samples https://github.com/openfl/lime-samples --quiet + + - name: Build HelloWorld sample + run: | + lime create HelloWorld -verbose -nocolor + lime build HelloWorld linux -release -verbose -nocolor + + - name: Build SimpleImage sample + run: | + lime create SimpleImage -verbose -nocolor + lime build SimpleImage linux -release -verbose -nocolor + + - name: Build SimpleAudio sample + run: | + lime create SimpleAudio -verbose -nocolor + lime build SimpleAudio linux -release -verbose -nocolor + + macos: + runs-on: macos-12 steps: - uses: actions/checkout@v3 @@ -79,13 +101,13 @@ jobs: - uses: krdlab/setup-haxe@v1 with: - haxe-version: 4.2.5 + haxe-version: ${{ env.HAXE_VERSION }} - name: Set HAXEPATH run: | echo "HAXEPATH=$HAXE_STD_PATH/.." >> $GITHUB_ENV - - name: Install Haxe dependencies + - name: Install HashLink dependencies run: | pushd project/lib/hashlink brew update @@ -95,6 +117,9 @@ jobs: rm /usr/local/bin/python3* brew bundle popd + + - name: Install Haxe dependencies + run: | haxelib install hxcpp 4.2.1 --quiet haxelib install format --quiet haxelib install hxp --quiet @@ -105,7 +130,7 @@ jobs: - name: Rebuild Lime tools run: | - haxelib dev lime $GITHUB_WORKSPACE + haxelib dev lime ${{ github.workspace }} haxelib run lime rebuild tools -nocolor -verbose -nocffi haxelib run lime setup -alias -y -nocffi @@ -129,7 +154,26 @@ jobs: templates/bin/hl/Mac64 if-no-files-found: error - windows-ndll: + - name: Install samples + run: | + haxelib git lime-samples https://github.com/openfl/lime-samples --quiet + + # - name: Build HelloWorld sample + # run: | + # lime create HelloWorld -verbose -nocolor + # lime build HelloWorld macos -release -verbose -nocolor + + - name: Build SimpleImage sample + run: | + lime create SimpleImage -verbose -nocolor + lime build SimpleImage macos -release -verbose -nocolor + + - name: Build SimpleAudio sample + run: | + lime create SimpleAudio -verbose -nocolor + lime build SimpleAudio macos -release -verbose -nocolor + + windows: runs-on: windows-latest steps: @@ -139,7 +183,7 @@ jobs: - uses: krdlab/setup-haxe@v1 with: - haxe-version: 4.2.5 + haxe-version: ${{ env.HAXE_VERSION }} - name: Set HAXEPATH run: | @@ -157,7 +201,7 @@ jobs: - name: Rebuild Lime tools run: | - haxelib dev lime $Env:GITHUB_WORKSPACE + haxelib dev lime ${{ github.workspace }} haxelib run lime rebuild tools -nocolor -verbose -nocffi haxelib run lime setup -alias -y -nocffi @@ -196,9 +240,27 @@ jobs: templates/bin/hl/Windows64 if-no-files-found: error - android-ndll: - needs: macos-ndll - runs-on: macos-11 + - name: Install samples + run: | + haxelib git lime-samples https://github.com/openfl/lime-samples --quiet + + - name: Build HelloWorld sample + run: | + lime create HelloWorld -verbose -nocolor + lime build HelloWorld windows -release -verbose -nocolor + + - name: Build SimpleImage sample + run: | + lime create SimpleImage -verbose -nocolor + lime build SimpleImage windows -release -verbose -nocolor + + - name: Build SimpleAudio sample + run: | + lime create SimpleAudio -verbose -nocolor + lime build SimpleAudio windows -release -verbose -nocolor + + android: + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 @@ -218,7 +280,7 @@ jobs: - uses: krdlab/setup-haxe@v1 with: - haxe-version: 4.2.5 + haxe-version: ${{ env.HAXE_VERSION }} - name: Set HAXEPATH run: | @@ -234,28 +296,22 @@ jobs: run: | echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV - - name: Rebuild Lime tools + - name: Prepare Lime run: | - haxelib dev lime $GITHUB_WORKSPACE - haxelib run lime rebuild tools -nocolor -verbose -nocffi - haxelib run lime setup -alias -y -nocffi - - - uses: actions/download-artifact@v3 - with: - name: Mac64-NDLL - path: ndll/Mac64/ + haxelib dev lime ${{ github.workspace }} + haxelib run lime setup -alias -y -nocffi -eval - name: Configure Android support run: | - lime config ANDROID_SDK $ANDROID_HOME - lime config ANDROID_NDK_ROOT ${{ steps.setup-ndk.outputs.ndk-path }} - lime config JAVA_HOME $JAVA_HOME - lime config ANDROID_SETUP true - lime config + lime config ANDROID_SDK $ANDROID_HOME -eval + lime config ANDROID_NDK_ROOT ${{ steps.setup-ndk.outputs.ndk-path }} -eval + lime config JAVA_HOME $JAVA_HOME -eval + lime config ANDROID_SETUP true -eval + lime config -eval - name: Rebuild Lime (Android) run: | - lime rebuild android -release -nocolor -verbose -nocffi + lime rebuild android -release -nocolor -verbose -nocffi -eval - uses: actions/upload-artifact@v3 with: @@ -265,9 +321,26 @@ jobs: !**/.gitignore if-no-files-found: error - ios-ndll: - needs: macos-ndll - runs-on: macos-11 + - name: Install samples + run: | + haxelib git lime-samples https://github.com/openfl/lime-samples --quiet + + - name: Build HelloWorld sample + run: | + lime create HelloWorld -verbose -nocolor -eval + lime build HelloWorld android -release -verbose -nocolor -eval + + - name: Build SimpleImage sample + run: | + lime create SimpleImage -verbose -nocolor -eval + lime build SimpleImage android -release -verbose -nocolor -eval + + - name: Build SimpleAudio sample + run: | + lime create SimpleAudio -verbose -nocolor -eval + lime build SimpleAudio android -release -verbose -nocolor -eval + ios: + runs-on: macos-12 steps: - uses: actions/checkout@v3 @@ -276,7 +349,7 @@ jobs: - uses: krdlab/setup-haxe@v1 with: - haxe-version: 4.2.5 + haxe-version: ${{ env.HAXE_VERSION }} - name: Set HAXEPATH run: | @@ -292,20 +365,14 @@ jobs: run: | echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV - - name: Rebuild Lime tools + - name: Prepare Lime run: | - haxelib dev lime $GITHUB_WORKSPACE - haxelib run lime rebuild tools -nocolor -verbose -nocffi - haxelib run lime setup -alias -y -nocffi - - - uses: actions/download-artifact@v3 - with: - name: Mac64-NDLL - path: ndll/Mac64/ + haxelib dev lime ${{ github.workspace }} + haxelib run lime setup -alias -y -nocffi -eval - name: Rebuild Lime (iOS) run: | - lime rebuild ios -clean -release -verbose -nocolor + lime rebuild ios -clean -release -verbose -nocolor -eval - uses: actions/upload-artifact@v3 with: @@ -315,9 +382,28 @@ jobs: !**/.gitignore if-no-files-found: error + - name: Install samples + run: | + haxelib git lime-samples https://github.com/openfl/lime-samples --quiet + + # - name: Build HelloWorld sample + # run: | + # lime create HelloWorld -verbose -nocolor -eval + # lime build HelloWorld ios -simulator -release -verbose -nocolor -eval + + - name: Build SimpleImage sample + run: | + lime create SimpleImage -verbose -nocolor -eval + lime build SimpleImage ios -simulator -release -verbose -nocolor -eval + + - name: Build SimpleAudio sample + run: | + lime create SimpleAudio -verbose -nocolor -eval + lime build SimpleAudio ios -simulator -release -verbose -nocolor -eval + package-haxelib: - needs: [linux-ndll, macos-ndll, windows-ndll, android-ndll, ios-ndll] - runs-on: macos-11 + needs: [linux, macos, windows, android, ios] + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 @@ -326,7 +412,7 @@ jobs: - uses: krdlab/setup-haxe@v1 with: - haxe-version: 4.2.5 + haxe-version: ${{ env.HAXE_VERSION }} - name: Set HAXEPATH run: | @@ -337,6 +423,8 @@ jobs: haxelib install hxcpp 4.2.1 --quiet haxelib install format --quiet haxelib install hxp --quiet + haxelib install svg --quiet + haxelib install openfl --quiet - name: Enable HXCPP compile cache run: | @@ -344,7 +432,7 @@ jobs: - name: Rebuild Lime tools run: | - haxelib dev lime $GITHUB_WORKSPACE + haxelib dev lime ${{ github.workspace }} haxelib run lime rebuild tools -nocolor -verbose -nocffi haxelib run lime setup -alias -y -nocffi cp project/lib/hashlink/other/osx/entitlements.xml templates/bin/hl/entitlements.xml @@ -352,6 +440,7 @@ jobs: cp project/lib/hashlink/src/hlc.h templates/bin/hl/include/hlc.h cp project/lib/hashlink/src/hl.h templates/bin/hl/include/hl.h cp project/lib/hashlink/src/hlc_main.c templates/bin/hl/include/hlc_main.c + - uses: actions/download-artifact@v3 with: name: Android-NDLL @@ -407,6 +496,11 @@ jobs: name: Linux64-Hashlink path: templates/bin/hl/Linux64 + - name: Rebuild Lime svg.n + working-directory: tools + run: | + haxe svg.hxml + - uses: actions/upload-artifact@v3 with: name: lime-haxelib @@ -419,14 +513,14 @@ jobs: if-no-files-found: error docs: - runs-on: macos-11 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - uses: krdlab/setup-haxe@v1 with: - haxe-version: 4.2.5 + haxe-version: ${{ env.HAXE_VERSION }} - name: Set HAXEPATH run: | @@ -435,7 +529,7 @@ jobs: - name: Install Haxe dependencies run: | haxelib install dox --quiet - haxelib dev lime $GITHUB_WORKSPACE + haxelib dev lime ${{ github.workspace }} - name: Build docs working-directory: docs @@ -448,25 +542,15 @@ jobs: path: docs/pages if-no-files-found: error - android-samples: - needs: package-haxelib - runs-on: macos-11 + flash-samples: + runs-on: ubuntu-20.04 steps: - - name: Install Android NDK - uses: nttld/setup-ndk@v1 - id: setup-ndk - with: - ndk-version: r15c - - - uses: actions/setup-java@v3 - with: - distribution: "zulu" - java-version: 11 + - uses: actions/checkout@v3 - uses: krdlab/setup-haxe@v1 with: - haxe-version: 4.2.5 + haxe-version: ${{ env.HAXE_VERSION }} - name: Set HAXEPATH run: | @@ -474,95 +558,44 @@ jobs: - name: Install Haxe dependencies run: | - haxelib install hxcpp 4.2.1 --quiet haxelib install format --quiet haxelib install hxp --quiet haxelib git lime-samples https://github.com/openfl/lime-samples --quiet - - name: Enable HXCPP compile cache + - name: Prepare Lime run: | - echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV + haxelib dev lime ${{ github.workspace }} + haxelib run lime setup -alias -y -nocffi -eval - - uses: actions/download-artifact@v3 - with: - name: lime-haxelib - path: lime-haxelib - - - name: Prepare lime + - name: Build HelloWorld sample run: | - haxelib dev lime lime-haxelib - haxelib run lime setup -alias -y -nocffi + lime create HelloWorld -verbose -nocolor -eval + lime build HelloWorld flash -release -verbose -nocolor -eval - - name: Configure Android support + - name: Build SimpleImage sample run: | - lime config ANDROID_SDK $ANDROID_HOME - lime config ANDROID_NDK_ROOT ${{ steps.setup-ndk.outputs.ndk-path }} - lime config JAVA_HOME $JAVA_HOME - lime config ANDROID_SETUP true - lime config + lime create SimpleImage -verbose -nocolor -eval + lime build SimpleImage flash -release -verbose -nocolor -eval - - name: Create Lime samples + - name: Build SimpleAudio sample run: | - lime create HelloWorld -verbose -nocolor - lime create SimpleImage -verbose -nocolor - lime create SimpleAudio -verbose -nocolor - - - name: Build Lime samples - run: | - lime build HelloWorld android -release -verbose -nocolor - lime build SimpleImage android -release -verbose -nocolor - lime build SimpleAudio android -release -verbose -nocolor - - flash-samples: - needs: package-haxelib - runs-on: macos-11 - steps: - - - uses: krdlab/setup-haxe@v1 - with: - haxe-version: 4.2.5 - - - name: Set HAXEPATH - run: | - echo "HAXEPATH=$HAXE_STD_PATH/.." >> $GITHUB_ENV - - - name: Install Haxe dependencies - run: | - haxelib git lime-samples https://github.com/openfl/lime-samples --quiet - - - uses: actions/download-artifact@v3 - with: - name: lime-haxelib - path: lime-haxelib - - - name: Prepare lime - run: | - haxelib dev lime lime-haxelib - haxelib run lime setup -alias -y -nocffi - - - name: Create Lime samples - run: | - lime create HelloWorld -verbose -nocolor - lime create SimpleImage -verbose -nocolor - lime create SimpleAudio -verbose -nocolor - - - name: Build Lime samples - run: | - lime build HelloWorld flash -release -verbose -nocolor - lime build SimpleImage flash -release -verbose -nocolor - lime build SimpleAudio flash -release -verbose -nocolor + lime create SimpleAudio -verbose -nocolor -eval + lime build SimpleAudio flash -release -verbose -nocolor -eval air-samples: - needs: package-haxelib runs-on: windows-latest strategy: matrix: - haxe-version: [3.4.7, 4.0.5, 4.1.5, 4.2.5, 4.3.1] + haxe-version: [4.0.5, 4.1.5, 4.2.5, 4.3.1] steps: + - uses: actions/checkout@v3 + with: + submodules: true + - uses: krdlab/setup-haxe@v1 with: - haxe-version: 4.2.5 + haxe-version: ${{ matrix.haxe-version }} - uses: joshtynjala/setup-adobe-air-action@v2 with: @@ -575,41 +608,50 @@ jobs: - name: Install Haxe dependencies run: | + haxelib install hxcpp 4.2.1 --quiet + haxelib install format --quiet + haxelib install hxp --quiet haxelib git lime-samples https://github.com/openfl/lime-samples --quiet - - uses: actions/download-artifact@v3 - with: - name: lime-haxelib - path: lime-haxelib - - - name: Prepare lime + - name: Prepare Lime run: | - haxelib dev lime lime-haxelib - haxelib run lime setup -alias -y -nocffi - haxelib run lime config AIR_SDK ${{ env.AIR_HOME }} + haxelib dev lime ${{ github.workspace }} + haxelib run lime setup -alias -y -nocffi -eval + haxelib run lime config AIR_SDK ${{ env.AIR_HOME }} -eval - - name: Create Lime samples + - name: Build HelloWorld sample run: | - lime create HelloWorld -verbose -nocolor - lime create SimpleImage -verbose -nocolor - lime create SimpleAudio -verbose -nocolor + lime create HelloWorld -verbose -nocolor -eval + lime build HelloWorld air -release -verbose -nocolor -eval - - name: Build Lime samples + - name: Build SimpleImage sample run: | - lime build HelloWorld air -release -verbose -nocolor - lime build SimpleImage air -release -verbose -nocolor - lime build SimpleAudio air -release -verbose -nocolor + lime create SimpleImage -verbose -nocolor -eval + lime build SimpleImage air -release -verbose -nocolor -eval + + - name: Build SimpleAudio sample + run: | + lime create SimpleAudio -verbose -nocolor -eval + lime build SimpleAudio air -release -verbose -nocolor -eval hashlink-samples: needs: package-haxelib - runs-on: ubuntu-20.04 + strategy: + matrix: + os: [windows-latest, ubuntu-20.04, macos-12] + runs-on: ${{ matrix.os }} steps: - uses: krdlab/setup-haxe@v1 with: - haxe-version: 4.3.3 + haxe-version: ${{ env.HAXE_VERSION }} - - name: Set HAXEPATH + - name: Set HAXEPATH (Windows) + if: runner.os == 'Windows' + run: | + echo "HAXEPATH=$Env:HAXE_STD_PATH\.." >> $Env:GITHUB_ENV + - name: Set HAXEPATH (Mac/Linux) + if: runner.os != 'Windows' run: | echo "HAXEPATH=$HAXE_STD_PATH/.." >> $GITHUB_ENV @@ -622,37 +664,85 @@ jobs: name: lime-haxelib path: lime-haxelib - - name: Prepare lime + - name: Prepare Lime run: | haxelib dev lime lime-haxelib haxelib run lime setup -alias -y -nocffi - - name: Create Lime samples + - name: Build HelloWorld sample run: | lime create HelloWorld -verbose -nocolor - lime create SimpleImage -verbose -nocolor - lime create SimpleAudio -verbose -nocolor - - - name: Build Lime samples (HL/JIT) - run: | lime build HelloWorld hl -release -verbose -nocolor + + - name: Build SimpleImage sample + run: | + lime create SimpleImage -verbose -nocolor lime build SimpleImage hl -release -verbose -nocolor + + - name: Build SimpleAudio sample + run: | + lime create SimpleAudio -verbose -nocolor lime build SimpleAudio hl -release -verbose -nocolor - - name: Build Lime samples (HL/C) + hashlinkc-samples: + needs: package-haxelib + strategy: + matrix: + os: [windows-latest, ubuntu-20.04, macos-12] + runs-on: ${{ matrix.os }} + steps: + + - uses: krdlab/setup-haxe@v1 + with: + haxe-version: 4.3.3 # minimum required version for HL/C + + - name: Set HAXEPATH (Windows) + if: runner.os == 'Windows' run: | + echo "HAXEPATH=$Env:HAXE_STD_PATH\.." >> $Env:GITHUB_ENV + - name: Set HAXEPATH (Mac/Linux) + if: runner.os != 'Windows' + run: | + echo "HAXEPATH=$HAXE_STD_PATH/.." >> $GITHUB_ENV + + - name: Install Haxe dependencies + run: | + haxelib git lime-samples https://github.com/openfl/lime-samples --quiet + + - uses: actions/download-artifact@v3 + with: + name: lime-haxelib + path: lime-haxelib + + - name: Prepare Lime + run: | + haxelib dev lime lime-haxelib + haxelib run lime setup -alias -y -nocffi + + - name: Build HelloWorld sample + run: | + lime create HelloWorld -verbose -nocolor lime build HelloWorld hlc -release -verbose -nocolor + + - name: Build SimpleImage sample + run: | + lime create SimpleImage -verbose -nocolor lime build SimpleImage hlc -release -verbose -nocolor + + - name: Build SimpleAudio sample + run: | + lime create SimpleAudio -verbose -nocolor lime build SimpleAudio hlc -release -verbose -nocolor html5-samples: - needs: package-haxelib - runs-on: macos-11 + runs-on: ubuntu-20.04 steps: + - uses: actions/checkout@v3 + - uses: krdlab/setup-haxe@v1 with: - haxe-version: 4.2.5 + haxe-version: ${{ env.HAXE_VERSION }} - name: Set HAXEPATH run: | @@ -660,199 +750,65 @@ jobs: - name: Install Haxe dependencies run: | + haxelib install format --quiet + haxelib install hxp --quiet haxelib install genes --quiet haxelib git lime-samples https://github.com/openfl/lime-samples --quiet - - uses: actions/download-artifact@v3 - with: - name: lime-haxelib - path: lime-haxelib - - - name: Prepare lime + - name: Prepare Lime run: | - haxelib dev lime lime-haxelib - haxelib run lime setup -alias -y -nocffi + haxelib dev lime ${{ github.workspace }} + haxelib run lime setup -alias -y -nocffi -eval - - name: Create Lime samples + - name: Build HelloWorld sample run: | - lime create HelloWorld -verbose -nocolor - lime create SimpleImage -verbose -nocolor - lime create SimpleAudio -verbose -nocolor + lime create HelloWorld -verbose -nocolor -eval + lime build HelloWorld html5 -release -verbose -nocolor -eval - - name: Build Lime samples + - name: Build HelloWorld variants run: | - lime build HelloWorld html5 -release -verbose -nocolor - lime build SimpleImage html5 -release -verbose -nocolor - lime build SimpleAudio html5 -release -verbose -nocolor + lime build HelloWorld html5 -clean -release -verbose -nocolor --haxelib=genes -eval + lime build HelloWorld html5 -clean -release -verbose -nocolor -minify -terser -eval - - name: Build Lime samples with Genes + - name: Build SimpleImage sample run: | - lime build HelloWorld html5 -clean -release -verbose -nocolor --haxelib=genes - lime build SimpleImage html5 -clean -release -verbose -nocolor --haxelib=genes - lime build SimpleAudio html5 -clean -release -verbose -nocolor --haxelib=genes + lime create SimpleImage -verbose -nocolor -eval + lime build SimpleImage html5 -release -verbose -nocolor -eval - - name: Build Lime samples with Terser minification + - name: Build SimpleImage variants run: | - lime build HelloWorld html5 -clean -release -verbose -nocolor -minify -terser - lime build SimpleImage html5 -clean -release -verbose -nocolor -minify -terser - lime build SimpleAudio html5 -clean -release -verbose -nocolor -minify -terser + lime build SimpleImage html5 -clean -release -verbose -nocolor --haxelib=genes -eval + lime build SimpleImage html5 -clean -release -verbose -nocolor -minify -terser -eval - ios-samples: - needs: package-haxelib - runs-on: macos-11 - steps: - - - uses: krdlab/setup-haxe@v1 - with: - haxe-version: 4.2.5 - - - name: Set HAXEPATH + - name: Build SimpleAudio sample run: | - echo "HAXEPATH=$HAXE_STD_PATH/.." >> $GITHUB_ENV + lime create SimpleAudio -verbose -nocolor -eval + lime build SimpleAudio html5 -release -verbose -nocolor -eval - - name: Install Haxe dependencies + - name: Build SimpleAudio variants run: | - haxelib install hxcpp 4.2.1 --quiet - haxelib install format --quiet - haxelib install hxp --quiet - haxelib git lime-samples https://github.com/openfl/lime-samples --quiet - - - name: Enable HXCPP compile cache - run: | - echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV - - - uses: actions/download-artifact@v3 - with: - name: lime-haxelib - path: lime-haxelib - - - name: Prepare lime - run: | - haxelib dev lime lime-haxelib - haxelib run lime setup -alias -y -nocffi - - - name: Create Lime samples - run: | - lime create HelloWorld -verbose -nocolor - lime create SimpleImage -verbose -nocolor - lime create SimpleAudio -verbose -nocolor - - - name: Build Lime samples - run: | - lime build HelloWorld ios -simulator -release -verbose -nocolor - lime build SimpleImage ios -simulator -release -verbose -nocolor - lime build SimpleAudio ios -simulator -release -verbose -nocolor - - linux-samples: - needs: package-haxelib - runs-on: ubuntu-20.04 - steps: - - - name: Install system dependencies - run: | - sudo apt-get update - sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev g++-multilib gcc-multilib libasound2-dev libx11-dev libxext-dev libxi-dev libxrandr-dev libxinerama-dev - - - uses: krdlab/setup-haxe@v1 - with: - haxe-version: 4.2.5 - - - name: Set HAXEPATH - run: | - echo "HAXEPATH=$HAXE_STD_PATH/.." >> $GITHUB_ENV - - - name: Install Haxe dependencies - run: | - haxelib install hxcpp 4.2.1 --quiet - haxelib install format --quiet - haxelib install hxp --quiet - haxelib git lime-samples https://github.com/openfl/lime-samples --quiet - - - name: Enable HXCPP compile cache - run: | - echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV - - - uses: actions/download-artifact@v3 - with: - name: lime-haxelib - path: lime-haxelib - - - name: Prepare lime - run: | - haxelib dev lime lime-haxelib - haxelib run lime setup -alias -y -nocffi - - - name: Create Lime samples - run: | - lime create HelloWorld -verbose -nocolor - lime create SimpleImage -verbose -nocolor - lime create SimpleAudio -verbose -nocolor - - - name: Build Lime samples - run: | - lime build HelloWorld linux -release -verbose -nocolor - lime build SimpleImage linux -release -verbose -nocolor - lime build SimpleAudio linux -release -verbose -nocolor - - macos-samples: - needs: package-haxelib - runs-on: macos-11 - steps: - - - uses: krdlab/setup-haxe@v1 - with: - haxe-version: 4.2.5 - - - name: Set HAXEPATH - run: | - echo "HAXEPATH=$HAXE_STD_PATH/.." >> $GITHUB_ENV - - - name: Install Haxe dependencies - run: | - haxelib install hxcpp 4.2.1 --quiet - haxelib install format --quiet - haxelib install hxp --quiet - haxelib git lime-samples https://github.com/openfl/lime-samples --quiet - - - name: Enable HXCPP compile cache - run: | - echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV - - - uses: actions/download-artifact@v3 - with: - name: lime-haxelib - path: lime-haxelib - - - name: Prepare lime - run: | - haxelib dev lime lime-haxelib - haxelib run lime setup -alias -y -nocffi - - - name: Create Lime samples - run: | - lime create HelloWorld -verbose -nocolor - lime create SimpleImage -verbose -nocolor - lime create SimpleAudio -verbose -nocolor - - - name: Build Lime samples - run: | - lime build HelloWorld macos -release -verbose -nocolor - lime build SimpleImage macos -release -verbose -nocolor - lime build SimpleAudio macos -release -verbose -nocolor + lime build SimpleAudio html5 -clean -release -verbose -nocolor --haxelib=genes -eval + lime build SimpleAudio html5 -clean -release -verbose -nocolor -minify -terser -eval neko-samples: needs: package-haxelib - runs-on: ubuntu-20.04 strategy: matrix: - haxe-version: [3.4.7, 4.0.5, 4.1.5, 4.2.5, 4.3.1] + haxe-version: [3.4.7, 4.2.5] + os: [windows-latest, ubuntu-20.04, macos-12] + runs-on: ${{ matrix.os }} steps: - uses: krdlab/setup-haxe@v1 with: haxe-version: ${{ matrix.haxe-version }} - - name: Set HAXEPATH + - name: Set HAXEPATH (Windows) + if: runner.os == 'Windows' + run: | + echo "HAXEPATH=$Env:HAXE_STD_PATH\.." >> $Env:GITHUB_ENV + - name: Set HAXEPATH (Mac/Linux) + if: runner.os != 'Windows' run: | echo "HAXEPATH=$HAXE_STD_PATH/.." >> $GITHUB_ENV @@ -865,72 +821,29 @@ jobs: name: lime-haxelib path: lime-haxelib - - name: Prepare lime + - name: Prepare Lime run: | haxelib dev lime lime-haxelib haxelib run lime setup -alias -y -nocffi - - name: Create Lime samples + - name: Build HelloWorld sample run: | lime create HelloWorld -verbose -nocolor - lime create SimpleImage -verbose -nocolor - lime create SimpleAudio -verbose -nocolor - - - name: Build Lime samples - run: | lime build HelloWorld neko -release -verbose -nocolor - lime build SimpleImage neko -release -verbose -nocolor - lime build SimpleAudio neko -release -verbose -nocolor - windows-samples: - needs: package-haxelib - runs-on: windows-latest - steps: - - - uses: krdlab/setup-haxe@v1 - with: - haxe-version: 4.2.5 - - - name: Set HAXEPATH + - name: Build SimpleImage sample run: | - echo "HAXEPATH=$Env:HAXE_STD_PATH\.." >> $Env:GITHUB_ENV - - - name: Install Haxe dependencies - run: | - haxelib install hxcpp 4.2.1 --quiet - haxelib install format --quiet - haxelib install hxp --quiet - haxelib git lime-samples https://github.com/openfl/lime-samples --quiet - - - name: Enable HXCPP compile cache - run: | - echo "HXCPP_COMPILE_CACHE=C:\.hxcpp" >> $Env:GITHUB_ENV - - - uses: actions/download-artifact@v3 - with: - name: lime-haxelib - path: lime-haxelib - - - name: Prepare lime - run: | - haxelib dev lime lime-haxelib - haxelib run lime setup -alias -y -nocffi - - - name: Create Lime samples - run: | - lime create HelloWorld -verbose -nocolor lime create SimpleImage -verbose -nocolor - lime create SimpleAudio -verbose -nocolor + lime build SimpleImage neko -release -verbose -nocolor - - name: Build Lime samples + - name: Build SimpleAudio sample run: | - lime build HelloWorld windows -release -verbose -nocolor - lime build SimpleImage windows -release -verbose -nocolor - lime build SimpleAudio windows -release -verbose -nocolor + lime create SimpleAudio -verbose -nocolor + lime build SimpleAudio neko -release -verbose -nocolor notify: runs-on: ubuntu-20.04 - needs: [package-haxelib, docs, android-samples, flash-samples, air-samples, hashlink-samples, html5-samples, ios-samples, linux-samples, macos-samples, neko-samples, windows-samples] + needs: [package-haxelib, docs, android, flash-samples, air-samples, hashlink-samples, html5-samples, ios, linux, macos, neko-samples, windows] if: ${{ github.repository == 'openfl/lime' && github.event_name != 'pull_request' }} steps: - name: Notify Discord diff --git a/CHANGELOG.md b/CHANGELOG.md index 815525ba5..ab7304112 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,13 @@ Changelog ========= -8.1.0 (??/??/2023) +8.1.1 (11/08/2023) +------------------ + +* Fixed subset of characters escaped in file paths to fix Android builds on Windows. +* Fixed playback of very long sounds by changing arithmetic to avoid integer overflow. + +8.1.0 (10/16/2023) ------------------ * Added `visible` property to `Window` to allow it to be shown and hidden @@ -14,9 +20,8 @@ Changelog * Added `-terser` option to Lime tools for html5 builds to optionally use Terser minifier * Added `-npx` option to Lime tools to run minifiers, or Electron, using `npx` instead of the bundled versions * Updated the bundled version of Node.js to 18 LTS for the html5 target's HTTP server -* Modernized Android Gradle build options -* Exposed more information to _project.xml_, including `${project.platformType}` and `${config.android.target-sdk-version}` -* Added click count for mouse events, for use by OpenFL +* Exposed more information to _project.xml_, such as `${project.host}` and `${config.android.target-sdk-version}` +* Updated the Android Gradle plugin * Disabled pointer tagging on Android * Fixed issues in `emscripten` target and renamed it to `webassembly` * Fixed unpopulated `responseData` on `HTTPRequest` when server returns error status code diff --git a/LICENSE.md b/LICENSE.md index c6c85fd0d..726f005e6 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,7 +1,7 @@ MIT License =========== -Copyright (c) 2013-2023 Joshua Granick and other Lime contributors +Copyright (c) 2013-2024 Joshua Granick and other Lime contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/NOTICE.md b/NOTICE.md index 1d69d9649..9eba9c755 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -2,7 +2,7 @@ Notices ======= ### Lime -Copyright (c) 2013-2023 Joshua Granick and other Lime contributors +Copyright (c) 2013-2024 Joshua Granick and other Lime contributors This product bundles cairo 1.15.2, which is available under an "MPL 1.1" license. For details, see [project/lib/cairo/](project/lib). diff --git a/externs/air/sys/FileSystem.hx b/externs/air/sys/FileSystem.hx index bd5e31302..2502bf6cd 100644 --- a/externs/air/sys/FileSystem.hx +++ b/externs/air/sys/FileSystem.hx @@ -1,41 +1,65 @@ package sys; +import flash.filesystem.File in FlashFile; +import lime.utils.Log; + @:dce @:coreApi class FileSystem { public static function exists(path:String):Bool { - return false; + return new FlashFile(path).exists; } - public static function rename(path:String, newPath:String):Void {} + public static function rename(path:String, newPath:String):Void + { + new FlashFile(path).moveTo(new FlashFile(newPath)); + } public static function stat(path:String):sys.FileStat { + Log.warn("stat is not implemented"); return null; } public static function fullPath(relPath:String):String { - return null; + var flashFile = new FlashFile(relPath); + flashFile.canonicalize(); + return flashFile.nativePath; } public static function absolutePath(relPath:String):String { - return null; + return new FlashFile(relPath).nativePath; } public static function isDirectory(path:String):Bool { - return false; + return new FlashFile(path).isDirectory; } - public static function createDirectory(path:String):Void {} + public static function createDirectory(path:String):Void + { + new FlashFile(path).createDirectory(); + } - public static function deleteFile(path:String):Void {} + public static function deleteFile(path:String):Void + { + new FlashFile(path).deleteFile(); + } - public static function deleteDirectory(path:String):Void {} + public static function deleteDirectory(path:String):Void + { + new FlashFile(path).deleteDirectory(false); + } - public static function readDirectory(path:String):Array {} + public static function readDirectory(path:String):Array + { + return new FlashFile(path).getDirectoryListing().map(function(f:FlashFile):String + { + return f.name; + }); + } } diff --git a/externs/air/sys/io/File.hx b/externs/air/sys/io/File.hx index 55e659ffa..11ffd701e 100644 --- a/externs/air/sys/io/File.hx +++ b/externs/air/sys/io/File.hx @@ -1,8 +1,11 @@ package sys.io; +import flash.utils.ByteArray; import flash.filesystem.File in FlashFile; import flash.filesystem.FileMode; import flash.filesystem.FileStream; +import lime.utils.Log; +import haxe.io.Bytes; @:dce @:coreApi @@ -18,34 +21,62 @@ class File return content; } - public static function saveContent(path:String, content:String):Void {} + public static function saveContent(path:String, content:String):Void + { + var file = new FlashFile(path); + var stream = new FileStream(); + stream.open(file, FileMode.WRITE); + stream.writeUTFBytes(content); + stream.close(); + } public static function getBytes(path:String):haxe.io.Bytes { - return null; + var file = new FlashFile(path); + var stream = new FileStream(); + stream.open(file, FileMode.READ); + var byteArray = new ByteArray(); + stream.readBytes(byteArray, 0, stream.bytesAvailable); + stream.close(); + return Bytes.ofData(byteArray); } - public static function saveBytes(path:String, bytes:haxe.io.Bytes):Void {} + public static function saveBytes(path:String, bytes:haxe.io.Bytes):Void + { + var byteArray:ByteArray = bytes.getData(); + var file = new FlashFile(path); + var stream = new FileStream(); + stream.open(file, FileMode.WRITE); + stream.writeBytes(byteArray); + stream.close(); + } public static function read(path:String, binary:Bool = true):FileInput { + Log.warn("read is not implemented"); return null; } public static function write(path:String, binary:Bool = true):FileOutput { + Log.warn("write is not implemented"); return null; } public static function append(path:String, binary:Bool = true):FileOutput { + Log.warn("append is not implemented"); return null; } public static function update(path:String, binary:Bool = true):FileOutput { + Log.warn("update is not implemented"); return null; } - public static function copy(srcPath:String, dstPath:String):Void {} + public static function copy(srcPath:String, dstPath:String):Void + { + new FlashFile(srcPath).copyTo(new FlashFile(dstPath)); + } } diff --git a/project/src/net/curl/CURLBindings.cpp b/project/src/net/curl/CURLBindings.cpp index 2bbb095ea..861bb8536 100644 --- a/project/src/net/curl/CURLBindings.cpp +++ b/project/src/net/curl/CURLBindings.cpp @@ -718,7 +718,8 @@ namespace lime { pos->v.i = position; curl_gc_mutex.Unlock (); - length = *((int*)writeCallback->Call (bytes, pos)); + vdynamic* _length = (vdynamic*)writeCallback->Call (bytes, pos); + length = (_length != NULL ? _length->v.i : 0); curl_gc_mutex.Lock (); if (length == CURL_WRITEFUNC_PAUSE) { @@ -749,7 +750,8 @@ namespace lime { ulnow->v.d = progress->ulnow; curl_gc_mutex.Unlock (); - code = *((int*)progressCallback->Call (dltotal, dlnow, ultotal, ulnow)); + vdynamic* _code = (vdynamic*)progressCallback->Call (dltotal, dlnow, ultotal, ulnow); + code = (_code != NULL ? _code->v.i : 0); curl_gc_mutex.Lock (); if (code != 0) { // CURLE_OK @@ -776,7 +778,8 @@ namespace lime { ulnow->v.i = xferInfo->ulnow; curl_gc_mutex.Unlock (); - code = *((int*)xferInfoCallback->Call (dltotal, dlnow, ultotal, ulnow)); + vdynamic* _code = (vdynamic*)xferInfoCallback->Call (dltotal, dlnow, ultotal, ulnow); + code = (_code != NULL ? _code->v.i : 0); curl_gc_mutex.Lock (); if (code != 0) { @@ -1706,7 +1709,7 @@ namespace lime { } - progressCallbacks[handle] = new ValuePointer (parameter);; + progressCallbacks[handle] = new ValuePointer (parameter); progressValues[handle] = new CURL_Progress (); code = curl_easy_setopt (easy_handle, type, progress_callback); diff --git a/src/lime/_internal/backend/html5/HTML5Thread.hx b/src/lime/_internal/backend/html5/HTML5Thread.hx index 08e0b2b85..845a2924d 100644 --- a/src/lime/_internal/backend/html5/HTML5Thread.hx +++ b/src/lime/_internal/backend/html5/HTML5Thread.hx @@ -374,6 +374,14 @@ abstract WorkFunction(WorkFunctionData) from Wor #end return this.func; } + else if (this.sourceCode != null) + { + #if !macro + this.func = #if !haxe4 untyped __js__ #else Syntax.code #end + ('new Function("return " + {0})()', this.sourceCode); + #end + return this.func; + } throw 'Object is not a valid WorkFunction: $this'; } @@ -401,11 +409,26 @@ abstract WorkFunction(WorkFunctionData) from Wor { // All set. this.func = null; + return true; } #end } else { + #if !macro + this.sourceCode = (cast this.func:Function).toString(); + if (this.sourceCode.indexOf("[native code]") < 0) + { + // All set. + this.func = null; + return true; + } + else + { + this.sourceCode = null; + } + #end + // If you aren't sure why you got this message, make sure your // variables are of type `WorkFunction`. // This won't work: @@ -436,6 +459,7 @@ abstract WorkFunction(WorkFunctionData) from Wor typedef WorkFunctionData = { @:optional var classPath:String; @:optional var functionName:String; + @:optional var sourceCode:String; @:optional var func:T; }; diff --git a/src/lime/_internal/backend/native/NativeApplication.hx b/src/lime/_internal/backend/native/NativeApplication.hx index 1bf1299bd..2208624bf 100644 --- a/src/lime/_internal/backend/native/NativeApplication.hx +++ b/src/lime/_internal/backend/native/NativeApplication.hx @@ -8,6 +8,7 @@ import lime.graphics.OpenGLRenderContext; import lime.graphics.RenderContext; import lime.math.Rectangle; import lime.media.AudioManager; +import lime.system.CFFI; import lime.system.Clipboard; import lime.system.Display; import lime.system.DisplayMode; @@ -187,7 +188,7 @@ class NativeApplication { for (window in parent.windows) { - window.onDropFile.dispatch(#if hl @:privateAccess String.fromUTF8(dropEventInfo.file) #else dropEventInfo.file #end); + window.onDropFile.dispatch(CFFI.stringValue(dropEventInfo.file)); } } @@ -426,10 +427,10 @@ class NativeApplication switch (textEventInfo.type) { case TEXT_INPUT: - window.onTextInput.dispatch(#if hl @:privateAccess String.fromUTF8(textEventInfo.text) #else textEventInfo.text #end); + window.onTextInput.dispatch(CFFI.stringValue(textEventInfo.text)); case TEXT_EDIT: - window.onTextEdit.dispatch(#if hl @:privateAccess String.fromUTF8(textEventInfo.text) #else textEventInfo.text #end, textEventInfo.start, + window.onTextEdit.dispatch(CFFI.stringValue(textEventInfo.text), textEventInfo.start, textEventInfo.length); default: diff --git a/src/lime/_internal/backend/native/NativeAudioSource.hx b/src/lime/_internal/backend/native/NativeAudioSource.hx index 37c04fb79..ab85e0e00 100644 --- a/src/lime/_internal/backend/native/NativeAudioSource.hx +++ b/src/lime/_internal/backend/native/NativeAudioSource.hx @@ -136,7 +136,7 @@ class NativeAudioSource } } - samples = Std.int((dataLength * 8) / (parent.buffer.channels * parent.buffer.bitsPerSample)); + samples = Std.int((dataLength * 8.0) / (parent.buffer.channels * parent.buffer.bitsPerSample)); } public function play():Void diff --git a/src/lime/_internal/backend/native/NativeHTTPRequest.hx b/src/lime/_internal/backend/native/NativeHTTPRequest.hx index f5ecea072..026d23f96 100644 --- a/src/lime/_internal/backend/native/NativeHTTPRequest.hx +++ b/src/lime/_internal/backend/native/NativeHTTPRequest.hx @@ -377,7 +377,7 @@ class NativeHTTPRequest } } - private function curl_onProgress(curl:CURL, dltotal:Float, dlnow:Float, uptotal:Float, upnow:Float):Void + private function curl_onProgress(curl:CURL, dltotal:Float, dlnow:Float, uptotal:Float, upnow:Float):Int { if (upnow > writeBytesLoaded || dlnow > writeBytesLoaded || uptotal > writeBytesTotal || dltotal > writeBytesTotal) { @@ -389,6 +389,8 @@ class NativeHTTPRequest // Wrong thread // promise.progress (bytesLoaded, bytesTotal); } + + return 0; } private function curl_onWrite(curl:CURL, output:Bytes):Int diff --git a/src/lime/_internal/backend/native/NativeOpenGLRenderContext.hx b/src/lime/_internal/backend/native/NativeOpenGLRenderContext.hx index 24280a018..68a8e512e 100644 --- a/src/lime/_internal/backend/native/NativeOpenGLRenderContext.hx +++ b/src/lime/_internal/backend/native/NativeOpenGLRenderContext.hx @@ -20,6 +20,7 @@ import lime.graphics.opengl.GLTexture; import lime.graphics.opengl.GLUniformLocation; import lime.graphics.opengl.GL; import lime.graphics.RenderContextType; +import lime.system.CFFI; import lime.utils.DataPointer; import lime.utils.Float32Array; import lime.utils.Int32Array; @@ -1395,7 +1396,7 @@ class NativeOpenGLRenderContext return { size: result.size, type: result.type, - name: @:privateAccess String.fromUTF8(result.name) + name: CFFI.stringValue(result.name) }; } else @@ -1420,7 +1421,7 @@ class NativeOpenGLRenderContext return { size: result.size, type: result.type, - name: @:privateAccess String.fromUTF8(result.name) + name: CFFI.stringValue(result.name) }; } else @@ -1455,10 +1456,7 @@ class NativeOpenGLRenderContext { #if (lime_cffi && (lime_opengl || lime_opengles) && !macro) var result = NativeCFFI.lime_gl_get_active_uniform_block_name(__getObjectID(program), uniformBlockIndex); - #if hl - var result = @:privateAccess String.fromUTF8(result); - #end - return result; + return CFFI.stringValue(result); #else return null; #end @@ -1901,10 +1899,7 @@ class NativeOpenGLRenderContext { #if (lime_cffi && (lime_opengl || lime_opengles) && !macro) var result = NativeCFFI.lime_gl_get_program_info_log(__getObjectID(program)); - #if hl - var result = @:privateAccess String.fromUTF8(result); - #end - return result; + return CFFI.stringValue(result); #else return null; #end @@ -2039,10 +2034,7 @@ class NativeOpenGLRenderContext { #if (lime_cffi && (lime_opengl || lime_opengles) && !macro) var result = NativeCFFI.lime_gl_get_shader_info_log(__getObjectID(shader)); - #if hl - var result = (result != null) ? @:privateAccess String.fromUTF8(result) : null; - #end - return result; + return CFFI.stringValue(result); #else return null; #end @@ -2066,10 +2058,7 @@ class NativeOpenGLRenderContext { #if (lime_cffi && (lime_opengl || lime_opengles) && !macro) var result = NativeCFFI.lime_gl_get_shader_source(__getObjectID(shader)); - #if hl - var result = @:privateAccess String.fromUTF8(result); - #end - return result; + return CFFI.stringValue(result); #else return null; #end @@ -2079,10 +2068,7 @@ class NativeOpenGLRenderContext { #if (lime_cffi && (lime_opengl || lime_opengles) && !macro) var result = NativeCFFI.lime_gl_get_string(name); - #if hl - var result = @:privateAccess String.fromUTF8(result); - #end - return result; + return CFFI.stringValue(result); #else return null; #end @@ -2092,10 +2078,7 @@ class NativeOpenGLRenderContext { #if (lime_cffi && (lime_opengl || lime_opengles) && !macro) var result = NativeCFFI.lime_gl_get_stringi(name, index); - #if hl - var result = @:privateAccess String.fromUTF8(result); - #end - return result; + return CFFI.stringValue(result); #else return null; #end @@ -2207,7 +2190,7 @@ class NativeOpenGLRenderContext return { size: result.size, type: result.type, - name: @:privateAccess String.fromUTF8(result.name) + name: CFFI.stringValue(result.name) }; } else diff --git a/src/lime/_internal/backend/native/NativeWindow.hx b/src/lime/_internal/backend/native/NativeWindow.hx index b7f900184..0f9295035 100644 --- a/src/lime/_internal/backend/native/NativeWindow.hx +++ b/src/lime/_internal/backend/native/NativeWindow.hx @@ -15,6 +15,7 @@ import lime.graphics.OpenGLRenderContext; import lime.graphics.RenderContext; import lime.math.Rectangle; import lime.math.Vector2; +import lime.system.CFFI; import lime.system.Display; import lime.system.DisplayMode; import lime.system.JNI; @@ -123,11 +124,7 @@ class NativeWindow var context = new RenderContext(); context.window = parent; - #if hl - var contextType = @:privateAccess String.fromUTF8(NativeCFFI.lime_window_get_context_type(handle)); - #else - var contextType:String = NativeCFFI.lime_window_get_context_type(handle); - #end + var contextType:String = CFFI.stringValue(NativeCFFI.lime_window_get_context_type(handle)); switch (contextType) { diff --git a/src/lime/app/Future.hx b/src/lime/app/Future.hx index 2df1895d8..2af97182d 100644 --- a/src/lime/app/Future.hx +++ b/src/lime/app/Future.hx @@ -77,6 +77,13 @@ import lime.utils.Log; var promise = new Promise(); promise.future = this; + #if (lime_threads && html5) + if (useThreads) + { + work.makePortable(); + } + #end + FutureWork.run(dispatchWorkFunction, work, promise, useThreads ? MULTI_THREADED : SINGLE_THREADED, true); } } diff --git a/src/lime/graphics/cairo/Cairo.hx b/src/lime/graphics/cairo/Cairo.hx index ed113b2a0..5dca32c8f 100644 --- a/src/lime/graphics/cairo/Cairo.hx +++ b/src/lime/graphics/cairo/Cairo.hx @@ -762,11 +762,7 @@ class Cairo private static function get_versionString():String { #if (lime_cffi && lime_cairo && !macro) - #if hl - return @:privateAccess String.fromUTF8(NativeCFFI.lime_cairo_version_string()); - #else - return NativeCFFI.lime_cairo_version_string(); - #end + return CFFI.stringValue(NativeCFFI.lime_cairo_version_string()); #else return ""; #end diff --git a/src/lime/media/WebAudioContext.hx b/src/lime/media/WebAudioContext.hx index e03f9fac0..89dac24a3 100644 --- a/src/lime/media/WebAudioContext.hx +++ b/src/lime/media/WebAudioContext.hx @@ -13,6 +13,13 @@ class WebAudioContext public function new() {} + #if (haxe_ver >= 4.2) + public function resume():Dynamic /*Promise*/ + { + return null; + } + #end + public function createAnalyser():Dynamic /*AnalyserNode*/ { return null; diff --git a/src/lime/media/openal/AL.hx b/src/lime/media/openal/AL.hx index 044564a39..f8fced192 100644 --- a/src/lime/media/openal/AL.hx +++ b/src/lime/media/openal/AL.hx @@ -2,6 +2,7 @@ package lime.media.openal; #if (!lime_doc_gen || lime_openal) import lime._internal.backend.native.NativeCFFI; +import lime.system.CFFI; import lime.system.CFFIPointer; import lime.utils.ArrayBufferView; @@ -998,10 +999,7 @@ class AL { #if (lime_cffi && lime_openal && !macro) var result = NativeCFFI.lime_al_get_string(param); - #if hl - var result = @:privateAccess String.fromUTF8(result); - #end - return result; + return CFFI.stringValue(result); #else return null; #end diff --git a/src/lime/media/openal/ALC.hx b/src/lime/media/openal/ALC.hx index 61d608464..62a3b6e26 100644 --- a/src/lime/media/openal/ALC.hx +++ b/src/lime/media/openal/ALC.hx @@ -2,6 +2,7 @@ package lime.media.openal; #if (!lime_doc_gen || lime_openal) import lime._internal.backend.native.NativeCFFI; +import lime.system.CFFI; import lime.system.CFFIPointer; #if !lime_debug @@ -144,10 +145,7 @@ class ALC { #if (lime_cffi && lime_openal && !macro) var result = NativeCFFI.lime_alc_get_string(device, param); - #if hl - var result = @:privateAccess String.fromUTF8(result); - #end - return result; + return CFFI.stringValue(result); #else return null; #end diff --git a/src/lime/net/curl/CURL.hx b/src/lime/net/curl/CURL.hx index 16a68edca..9f7bf0f28 100644 --- a/src/lime/net/curl/CURL.hx +++ b/src/lime/net/curl/CURL.hx @@ -3,6 +3,7 @@ package lime.net.curl; #if (!lime_doc_gen || lime_curl) import haxe.io.Bytes; import lime._internal.backend.native.NativeCFFI; +import lime.system.CFFI; import lime.system.CFFIPointer; #if !lime_debug @@ -57,10 +58,7 @@ class CURL { #if (lime_cffi && lime_curl && !macro) var result = NativeCFFI.lime_curl_easy_escape(handle, url, length); - #if hl - var result = @:privateAccess String.fromUTF8(result); - #end - return result; + return CFFI.stringValue(result); #else return null; #end @@ -187,17 +185,10 @@ class CURL case CURLOption.HEADERFUNCTION: var callback:CURL->String->Void = cast parameter; - #if hl - parameter = function(header:hl.Bytes) + parameter = function(header) { - callback(this, @:privateAccess String.fromUTF8(header)); + callback(this, CFFI.stringValue(header)); } - #else - parameter = function(header:String) - { - callback(this, header); - } - #end case CURLOption.HTTPHEADER: #if hl @@ -221,10 +212,7 @@ class CURL { #if (lime_cffi && lime_curl && !macro) var result = NativeCFFI.lime_curl_easy_strerror(cast(code, Int)); - #if hl - var result = @:privateAccess String.fromUTF8(result); - #end - return result; + return CFFI.stringValue(result); #else return null; #end @@ -234,10 +222,7 @@ class CURL { #if (lime_cffi && lime_curl && !macro) var result = NativeCFFI.lime_curl_easy_unescape(handle, url, inLength, outLength); - #if hl - var result = @:privateAccess String.fromUTF8(result); - #end - return result; + return CFFI.stringValue(result); #else return null; #end @@ -247,10 +232,7 @@ class CURL { #if (lime_cffi && lime_curl && !macro) var result = NativeCFFI.lime_curl_version(); - #if hl - var result = @:privateAccess String.fromUTF8(result); - #end - return result; + return CFFI.stringValue(result); #else return null; #end diff --git a/src/lime/system/CFFI.hx b/src/lime/system/CFFI.hx index fed0f62d4..096a766b4 100644 --- a/src/lime/system/CFFI.hx +++ b/src/lime/system/CFFI.hx @@ -204,6 +204,15 @@ class CFFI #end } + @:dox(hide) #if !hl inline #end public static function stringValue(#if hl value:hl.Bytes #else value:String #end):String + { + #if hl + return value != null ? @:privateAccess String.fromUTF8(value) : null; + #else + return value; + #end + } + private static function __findHaxelib(library:String):String { #if (sys && !macro && !html5) diff --git a/src/lime/system/Clipboard.hx b/src/lime/system/Clipboard.hx index 3bd98914b..d5653cd83 100644 --- a/src/lime/system/Clipboard.hx +++ b/src/lime/system/Clipboard.hx @@ -3,6 +3,7 @@ package lime.system; import lime._internal.backend.native.NativeCFFI; import lime.app.Application; import lime.app.Event; +import lime.system.CFFI; #if flash import flash.desktop.Clipboard as FlashClipboard; #elseif (js && html5) @@ -28,15 +29,7 @@ class Clipboard _text = null; #if (lime_cffi && !macro) - #if hl - var utf = NativeCFFI.lime_clipboard_get_text(); - if (utf != null) - { - _text = @:privateAccess String.fromUTF8(utf); - } - #else - _text = NativeCFFI.lime_clipboard_get_text(); - #end + _text = CFFI.stringValue(NativeCFFI.lime_clipboard_get_text()); #elseif flash if (FlashClipboard.generalClipboard.hasFormat(TEXT_FORMAT)) { diff --git a/src/lime/system/Locale.hx b/src/lime/system/Locale.hx index 25206e112..9967ac77a 100644 --- a/src/lime/system/Locale.hx +++ b/src/lime/system/Locale.hx @@ -68,8 +68,7 @@ abstract Locale(String) from String to String locale = toString(getDefault()); #elseif (lime_cffi && !macro) #if hl - var _locale = lime_locale_get_system_locale(); - locale = _locale != null ? @:privateAccess String.fromUTF8(_locale) : null; + locale = CFFI.stringValue(lime_locale_get_system_locale()); #else locale = CFFI.load("lime", "lime_locale_get_system_locale", 0)(); #end diff --git a/src/lime/system/System.hx b/src/lime/system/System.hx index 005061521..1466569b9 100644 --- a/src/lime/system/System.hx +++ b/src/lime/system/System.hx @@ -32,9 +32,9 @@ import sys.io.Process; @:access(lime._internal.backend.native.NativeCFFI) @:access(lime.system.Display) @:access(lime.system.DisplayMode) -#if (cpp && windows && !HXCPP_MINGW && !lime_disable_gpu_hint) +#if (cpp && windows && !lime_disable_gpu_hint) @:cppFileCode(' -#if defined(HX_WINDOWS) +#if defined(HX_WINDOWS) && !defined(__MINGW32__) extern "C" { _declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001; _declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; @@ -176,11 +176,7 @@ class System { var display = new Display(); display.id = id; - #if hl - display.name = @:privateAccess String.fromUTF8(displayInfo.name); - #else - display.name = displayInfo.name; - #end + display.name = CFFI.stringValue(displayInfo.name); display.bounds = new Rectangle(displayInfo.bounds.x, displayInfo.bounds.y, displayInfo.bounds.width, displayInfo.bounds.height); #if ios @@ -377,19 +373,11 @@ class System } } - #if hl - path = @:privateAccess String.fromUTF8(NativeCFFI.lime_system_get_directory(type, company, file)); - #else - path = NativeCFFI.lime_system_get_directory(type, company, file); - #end + path = CFFI.stringValue(NativeCFFI.lime_system_get_directory(type, company, file)); } else { - #if hl - path = @:privateAccess String.fromUTF8(NativeCFFI.lime_system_get_directory(type, null, null)); - #else - path = NativeCFFI.lime_system_get_directory(type, null, null); - #end + path = CFFI.stringValue(NativeCFFI.lime_system_get_directory(type, null, null)); } #if windows @@ -601,11 +589,7 @@ class System if (__deviceModel == null) { #if (lime_cffi && !macro && (windows || ios || tvos)) - #if hl - __deviceModel = @:privateAccess String.fromUTF8(NativeCFFI.lime_system_get_device_model()); - #else - __deviceModel = NativeCFFI.lime_system_get_device_model(); - #end + __deviceModel = CFFI.stringValue(NativeCFFI.lime_system_get_device_model()); #elseif android var manufacturer:String = JNI.createStaticField("android/os/Build", "MANUFACTURER", "Ljava/lang/String;").get(); var model:String = JNI.createStaticField("android/os/Build", "MODEL", "Ljava/lang/String;").get(); @@ -636,11 +620,7 @@ class System if (__deviceVendor == null) { #if (lime_cffi && !macro && windows && !html5) - #if hl - __deviceVendor = @:privateAccess String.fromUTF8(NativeCFFI.lime_system_get_device_vendor()); - #else - __deviceVendor = NativeCFFI.lime_system_get_device_vendor(); - #end + __deviceVendor = CFFI.stringValue(NativeCFFI.lime_system_get_device_vendor()); #elseif android var vendor:String = JNI.createStaticField("android/os/Build", "MANUFACTURER", "Ljava/lang/String;").get(); if (vendor != null) @@ -722,11 +702,7 @@ class System if (__platformLabel == null) { #if (lime_cffi && !macro && windows && !html5) - #if hl - var label:String = @:privateAccess String.fromUTF8(NativeCFFI.lime_system_get_platform_label()); - #else - var label:String = NativeCFFI.lime_system_get_platform_label(); - #end + var label:String = CFFI.stringValue(NativeCFFI.lime_system_get_platform_label()); if (label != null) __platformLabel = StringTools.trim(label); #elseif linux __platformLabel = __runProcess("lsb_release", ["-ds"]); @@ -784,11 +760,7 @@ class System if (__platformVersion == null) { #if (lime_cffi && !macro && windows && !html5) - #if hl - __platformVersion = @:privateAccess String.fromUTF8(NativeCFFI.lime_system_get_platform_version()); - #else - __platformVersion = NativeCFFI.lime_system_get_platform_version(); - #end + __platformVersion = CFFI.stringValue(NativeCFFI.lime_system_get_platform_version()); #elseif android var release = JNI.createStaticField("android/os/Build$VERSION", "RELEASE", "Ljava/lang/String;").get(); var api = JNI.createStaticField("android/os/Build$VERSION", "SDK_INT", "I").get(); diff --git a/src/lime/text/Font.hx b/src/lime/text/Font.hx index 30681e3d7..b5f36804d 100644 --- a/src/lime/text/Font.hx +++ b/src/lime/text/Font.hx @@ -8,6 +8,7 @@ import lime.graphics.Image; import lime.graphics.ImageBuffer; import lime.math.Vector2; import lime.net.HTTPRequest; +import lime.system.CFFI; import lime.system.System; import lime.utils.Assets; import lime.utils.Log; @@ -472,11 +473,7 @@ class Font { if (name == null) { - #if hl - name = @:privateAccess String.fromUTF8(NativeCFFI.lime_font_get_family_name(src)); - #else - name = cast NativeCFFI.lime_font_get_family_name(src); - #end + name = CFFI.stringValue(cast NativeCFFI.lime_font_get_family_name(src)); } ascender = NativeCFFI.lime_font_get_ascender(src); diff --git a/src/lime/text/harfbuzz/HBFont.hx b/src/lime/text/harfbuzz/HBFont.hx index 333cfd4e7..cac9e6fab 100644 --- a/src/lime/text/harfbuzz/HBFont.hx +++ b/src/lime/text/harfbuzz/HBFont.hx @@ -3,6 +3,7 @@ package lime.text.harfbuzz; #if (!lime_doc_gen || lime_harfbuzz) import lime._internal.backend.native.NativeCFFI; import lime.math.Vector2; +import lime.system.CFFI; import lime.system.CFFIPointer; @:access(lime._internal.backend.native.NativeCFFI) @@ -81,10 +82,7 @@ abstract HBFont(CFFIPointer) from CFFIPointer to CFFIPointer { #if (lime_cffi && lime_harfbuzz && !macro) var result = NativeCFFI.lime_hb_font_glyph_to_string(this, codepoint); - #if hl - var result = @:privateAccess String.fromUTF8(result); - #end - return result; + return CFFI.stringValue(result); #else return null; #end diff --git a/src/lime/text/harfbuzz/HBLanguage.hx b/src/lime/text/harfbuzz/HBLanguage.hx index cc5f01ed1..6912a66ae 100644 --- a/src/lime/text/harfbuzz/HBLanguage.hx +++ b/src/lime/text/harfbuzz/HBLanguage.hx @@ -2,6 +2,7 @@ package lime.text.harfbuzz; #if (!lime_doc_gen || lime_harfbuzz) import lime._internal.backend.native.NativeCFFI; +import lime.system.CFFI; import lime.system.CFFIPointer; @:access(lime._internal.backend.native.NativeCFFI) @@ -29,10 +30,7 @@ abstract HBLanguage(CFFIPointer) from CFFIPointer to CFFIPointer if (this != null) { var result = NativeCFFI.lime_hb_language_to_string(this); - #if hl - var result = @:privateAccess String.fromUTF8(result); - #end - return result; + return CFFI.stringValue(result); } #end return null; diff --git a/src/lime/tools/ConfigData.hx b/src/lime/tools/ConfigData.hx index 7520169d5..d86981420 100644 --- a/src/lime/tools/ConfigData.hx +++ b/src/lime/tools/ConfigData.hx @@ -9,6 +9,8 @@ import haxe.xml.Fast as Access; abstract ConfigData(Dynamic) to Dynamic from Dynamic { + private static inline var ARRAY:String = "___array"; + public function new() { this = {}; @@ -32,39 +34,12 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic public function exists(id:String):Bool { - var tree = id.split('.'); - - if (tree.length <= 1) - { - return Reflect.hasField(this, id); - } - - var current = this; - - for (leaf in tree) - { - if (Reflect.hasField(current, leaf)) - { - current = Reflect.field(current, leaf); - } - else - { - return false; - } - } - - return true; + return get(id) != null; } public function get(id:String):ConfigData { - var tree = id.split('.'); - - if (tree.length <= 1) - { - return Reflect.field(this, id); - } - + var tree = id.split("."); var current = this; for (leaf in tree) @@ -82,41 +57,29 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic public function getArray(id:String, defaultValue:Array = null):Array { - var tree = id.split('.'); + var tree = id.split("."); var array:Array = null; - if (tree.length <= 1) - { - array = Reflect.field(this, id + "___array"); + var current = this; + var field = tree.pop(); - if (array == null && Reflect.hasField(this, id)) + for (leaf in tree) + { + current = Reflect.field(current, leaf); + + if (current == null) { - array = [Reflect.field(this, id)]; + break; } } - else + + if (current != null) { - var current = this; - var field = tree.pop(); + array = Reflect.field(current, field + ARRAY); - for (leaf in tree) + if (array == null && Reflect.hasField(current, field)) { - current = Reflect.field(current, leaf); - - if (current == null) - { - break; - } - } - - if (current != null) - { - array = Reflect.field(current, field + "___array"); - - if (array == null && Reflect.hasField(current, field)) - { - array = [Reflect.field(current, field)]; - } + array = [Reflect.field(current, field)]; } } @@ -207,6 +170,32 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic return defaultValue; } + public function getKeyValueArray(id:String, defaultValues:Dynamic = null):Array<{ key:Dynamic, value:Dynamic }> + { + var values = {}; + if (defaultValues != null) + { + ObjectTools.copyFields(defaultValues, values); + } + + var data = get(id); + for (key in Reflect.fields(data)) + { + if (!StringTools.endsWith (key, ARRAY)) + { + Reflect.setField(values, key, Reflect.field(data, key)); + } + } + + var pairs = []; + for (key in Reflect.fields(values)) + { + pairs.push({ key: key, value: Reflect.field(values, key) }); + } + + return pairs; + } + private function log(v:Dynamic):Void { if (Log.verbose) @@ -227,7 +216,7 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic { for (field in Reflect.fields(source)) { - if (StringTools.endsWith(field, "___array")) + if (StringTools.endsWith(field, ARRAY)) { continue; } @@ -257,17 +246,17 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic if (doCopy && Reflect.field(source, field) != Reflect.field(destination, field) && typeSource != "TObject") { - if (!Reflect.hasField(destination, field + "___array")) + if (!Reflect.hasField(destination, field + ARRAY)) { - Reflect.setField(destination, field + "___array", [ObjectTools.deepCopy(Reflect.field(destination, field))]); + Reflect.setField(destination, field + ARRAY, [ObjectTools.deepCopy(Reflect.field(destination, field))]); } - var array:Array = Reflect.field(destination, field + "___array"); + var array:Array = Reflect.field(destination, field + ARRAY); - if (Reflect.hasField(source, field + "___array")) + if (Reflect.hasField(source, field + ARRAY)) { - array = array.concat(Reflect.field(source, field + "___array")); - Reflect.setField(destination, field + "___array", array); + array = array.concat(Reflect.field(source, field + ARRAY)); + Reflect.setField(destination, field + ARRAY, array); } else { @@ -289,9 +278,9 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic { Reflect.setField(destination, field, Reflect.field(source, field)); - if (Reflect.hasField(source, field + "___array")) + if (Reflect.hasField(source, field + ARRAY)) { - Reflect.setField(destination, field + "___array", Reflect.field(source, field + "___array")); + Reflect.setField(destination, field + ARRAY, Reflect.field(source, field + ARRAY)); } } } @@ -305,7 +294,7 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic if (StringTools.startsWith(elem.name, "config:")) { - var items = elem.name.split(':'); + var items = elem.name.split(":"); bucketType = items[1]; } @@ -353,12 +342,13 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic if (Reflect.hasField(bucket, child.name)) { - if (!Reflect.hasField(bucket, child.name + "___array")) + var array:Array = Reflect.field(bucket, child.name + ARRAY); + if (array == null) { - Reflect.setField(bucket, child.name + "___array", [ObjectTools.deepCopy(Reflect.field(bucket, child.name))]); + array = [ObjectTools.deepCopy(Reflect.field(bucket, child.name))]; + Reflect.setField(bucket, child.name + ARRAY, array); } - var array:Array = Reflect.field(bucket, child.name + "___array"); var arrayBucket = {}; array.push(arrayBucket); @@ -410,27 +400,9 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic } } - public function push(id:String, value:Dynamic):Void + public function push(id:String, value:Dynamic, ?unique:Bool = false):Void { - var tree = id.split('.'); - - if (tree.length <= 1) - { - if (Reflect.hasField(this, id)) - { - if (!Reflect.hasField(this, id + "___array")) - { - Reflect.setField(this, id + "___array", Reflect.hasField(this, id) ? [ObjectTools.deepCopy(Reflect.field(this, id))] : []); - } - - var array:Array = Reflect.field(this, id + "___array"); - array.push(value); - } - - Reflect.setField(this, id, value); - return; - } - + var tree = id.split("."); var current = this; var field = tree.pop(); @@ -454,13 +426,18 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic if (Reflect.hasField(current, field)) { - if (!Reflect.hasField(current, field + "___array")) + var array:Array = Reflect.field(current, field + ARRAY); + + if (array == null) { - Reflect.setField(current, field + "___array", Reflect.hasField(current, field) ? [ObjectTools.deepCopy(Reflect.field(current, field))] : []); + array = [ObjectTools.deepCopy(Reflect.field(current, field))]; + Reflect.setField(current, field + ARRAY, array); } - var array:Array = Reflect.field(current, field + "___array"); - array.push(value); + if (!unique || array.indexOf(value) == -1) + { + array.push(value); + } } Reflect.setField(current, field, value); @@ -468,14 +445,7 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic public function set(id:String, value:Dynamic):Void { - var tree = id.split('.'); - - if (tree.length <= 1) - { - Reflect.setField(this, id, value); - return; - } - + var tree = id.split("."); var current = this; var field = tree.pop(); @@ -525,12 +495,14 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic { if (typeSource != "TObject") { - if (!Reflect.hasField(bucket, node + "___array")) + var array:Array = Reflect.field(bucket, node + ARRAY); + if (array == null) { - Reflect.setField(bucket, node + "___array", [ObjectTools.deepCopy(Reflect.field(bucket, node))]); + array = [ObjectTools.deepCopy(Reflect.field(bucket, node))]; + Reflect.setField(bucket, node + ARRAY, array); } - cast(Reflect.field(bucket, node + "___array"), Array).push(value); + array.push(value); } Reflect.setField(bucket, node, value); diff --git a/src/lime/tools/HXProject.hx b/src/lime/tools/HXProject.hx index 9dd9fb7bb..d5d1cf1f8 100644 --- a/src/lime/tools/HXProject.hx +++ b/src/lime/tools/HXProject.hx @@ -60,6 +60,7 @@ class HXProject extends Script public var templatePaths:Array; @:isVar public var window(get, set):WindowData; public var windows:Array; + public var projectFilePath:String; private var needRerun:Bool; @@ -86,7 +87,7 @@ class HXProject extends Script var outputFile = args[1]; HXProject._command = inputData.command; - HXProject._target = cast inputData.target; + HXProject._target = inputData.target; HXProject._debug = inputData.debug; HXProject._targetFlags = inputData.targetFlags; HXProject._templatePaths = inputData.templatePaths; @@ -101,7 +102,7 @@ class HXProject extends Script Haxelib.debug = inputData.haxelibDebug; - initialize(); + initializeStatics(); var classRef = Type.resolveClass(inputData.name); var instance = Type.createInstance(classRef, []); @@ -113,11 +114,11 @@ class HXProject extends Script File.saveContent(outputFile, serializer.toString()); } - public function new() + public function new(defines:Map = null) { super(); - initialize(); + initializeStatics(); command = _command; config = new ConfigData(); @@ -161,13 +162,17 @@ class HXProject extends Script windows = [window]; assets = new Array(); - if (_userDefines != null) + if (defines != null) { - defines = MapTools.copy(_userDefines); + this.defines = MapTools.copy(defines); + } + else if (_userDefines != null) + { + this.defines = MapTools.copy(_userDefines); } else { - defines = new Map(); + this.defines = new Map(); } dependencies = new Array(); @@ -197,6 +202,8 @@ class HXProject extends Script samplePaths = new Array(); splashScreens = new Array(); targetHandlers = new Map(); + + initializeDefines(); } public function clone():HXProject @@ -660,15 +667,178 @@ class HXProject extends Script @:privateAccess projectXML.parseXML(new Access(Xml.parse(xml).firstElement()), ""); merge(projectXML); } - // #end - private static function initialize():Void + + private function initializeDefines():Void + { + switch (platformType) + { + case MOBILE: + defines.set("platformType", "mobile"); + defines.set("mobile", "1"); + + case DESKTOP: + defines.set("platformType", "desktop"); + defines.set("desktop", "1"); + + case WEB: + defines.set("platformType", "web"); + defines.set("web", "1"); + + case CONSOLE: + defines.set("platformType", "console"); + defines.set("console", "1"); + } + + if (targetFlags.exists("neko")) + { + defines.set("targetType", "neko"); + defines.set("native", "1"); + defines.set("neko", "1"); + } + else if (targetFlags.exists("hl")) + { + defines.set("targetType", "hl"); + defines.set("native", "1"); + defines.set("hl", "1"); + if (targetFlags.exists("hlc")) + { + defines.set("hlc", "1"); + } + } + else if (targetFlags.exists("java")) + { + defines.set("targetType", "java"); + defines.set("native", "1"); + defines.set("java", "1"); + } + else if (targetFlags.exists("nodejs")) + { + defines.set("targetType", "nodejs"); + defines.set("native", "1"); + defines.set("nodejs", "1"); + } + else if (targetFlags.exists("cs")) + { + defines.set("targetType", "cs"); + defines.set("native", "1"); + defines.set("cs", "1"); + } + else if (target == Platform.FIREFOX) + { + defines.set("targetType", "js"); + defines.set("html5", "1"); + } + else if (target == Platform.AIR) + { + defines.set("targetType", "swf"); + defines.set("flash", "1"); + if (targetFlags.exists("ios")) defines.set("ios", "1"); + if (targetFlags.exists("android")) defines.set("android", "1"); + } + else if (target == Platform.WINDOWS && (targetFlags.exists("uwp") || targetFlags.exists("winjs"))) + { + targetFlags.set("uwp", ""); + targetFlags.set("winjs", ""); + + defines.set("targetType", "js"); + defines.set("html5", "1"); + defines.set("uwp", "1"); + defines.set("winjs", "1"); + } + else if (platformType == DESKTOP && target != System.hostPlatform) + { + defines.set("native", "1"); + + if (target == Platform.WINDOWS && targetFlags.exists("mingw")) + { + defines.set("targetType", "cpp"); + defines.set("cpp", "1"); + defines.set("mingw", "1"); + } + else + { + defines.set("targetType", "neko"); + defines.set("neko", "1"); + } + } + else if (target == Platform.WEB_ASSEMBLY) + { + defines.set("webassembly", "1"); + defines.set("wasm", "1"); + defines.set("emscripten", "1"); + defines.set("targetType", "cpp"); + defines.set("native", "1"); + defines.set("cpp", "1"); + } + else if (targetFlags.exists("cpp") + || ((platformType != PlatformType.WEB) && !targetFlags.exists("html5"))) + { + defines.set("targetType", "cpp"); + defines.set("native", "1"); + defines.set("cpp", "1"); + } + else if (target == Platform.FLASH) + { + defines.set("targetType", "swf"); + } + + if (debug) + { + defines.set("buildType", "debug"); + defines.set("debug", "1"); + } + else if (targetFlags.exists("final")) + { + defines.set("buildType", "final"); + defines.set("final", "1"); + } + else + { + defines.set("buildType", "release"); + defines.set("release", "1"); + } + + if (targetFlags.exists("static")) + { + defines.set("static_link", "1"); + } + + if (defines.exists("SWF_PLAYER")) + { + environment.set("SWF_PLAYER", defines.get("SWF_PLAYER")); + } + + defines.set(Std.string(target).toLowerCase(), "1"); + defines.set("target", Std.string(target).toLowerCase()); + defines.set("platform", defines.get("target")); + + switch (System.hostPlatform) + { + case WINDOWS: + defines.set("host", "windows"); + case MAC: + defines.set("host", "mac"); + case LINUX: + defines.set("host", "linux"); + default: + defines.set("host", "unknown"); + } + + #if lime + defines.set("lime-tools", "1"); + #end + + defines.set("hxp", "1"); // TODO: Version? + } + + private static function initializeStatics():Void { if (!initialized) { if (_target == null) { - _target = cast System.hostPlatform; + _target = System.hostPlatform; } if (_targetFlags == null) @@ -740,6 +910,11 @@ class HXProject extends Script launchStoryboard.merge(project.launchStoryboard); } + if (projectFilePath == null) + { + projectFilePath = project.projectFilePath; + } + languages = ArrayTools.concatUnique(languages, project.languages, true); libraries = ArrayTools.concatUnique(libraries, project.libraries, true); @@ -869,7 +1044,7 @@ class HXProject extends Script // Getters & Setters private function get_host():Platform { - return cast System.hostPlatform; + return System.hostPlatform; } private function get_templateContext():Dynamic diff --git a/src/lime/tools/Platform.hx b/src/lime/tools/Platform.hx index 899ea7636..d799467d1 100644 --- a/src/lime/tools/Platform.hx +++ b/src/lime/tools/Platform.hx @@ -1,6 +1,6 @@ package lime.tools; -#if (haxe_ver >= 4.0) enum #else @:enum #end abstract Platform(String) +#if (haxe_ver >= 4.0) enum #else @:enum #end abstract Platform(String) from hxp.HostPlatform { var AIR = "air"; var ANDROID = "android"; @@ -24,4 +24,10 @@ package lime.tools; var EMSCRIPTEN = "emscripten"; var TVOS = "tvos"; var CUSTOM = null; + + @:op(A == B) @:commutative + private inline function equalsHostPlatform(hostPlatform:hxp.HostPlatform):Bool + { + return this == hostPlatform; + } } diff --git a/src/lime/tools/PlatformTarget.hx b/src/lime/tools/PlatformTarget.hx index a6232f4ba..87cf6e1d0 100644 --- a/src/lime/tools/PlatformTarget.hx +++ b/src/lime/tools/PlatformTarget.hx @@ -52,31 +52,39 @@ class PlatformTarget this.additionalArguments = additionalArguments; var metaFields = Meta.getFields(Type.getClass(this)); - if (/*!Reflect.hasField (metaFields.watch, "ignore") && */ (project.targetFlags.exists("watch"))) + // known issue: this may not log in `-eval` mode on Linux + inline function logCommand(command:String):Void + { + if (!Reflect.hasField(metaFields, command) + || !Reflect.hasField(Reflect.field(metaFields, command), "ignore")) + { + Log.info("", "\n" + Log.accentColor + "Running command: " + command.toUpperCase() + Log.resetColor); + } + } + + if (project.targetFlags.exists("watch")) { Log.info("", "\n" + Log.accentColor + "Running command: WATCH" + Log.resetColor); watch(); return; } - if ((!Reflect.hasField(metaFields, "display") || !Reflect.hasField(metaFields.display, "ignore")) && (command == "display")) + if (command == "display") { display(); } - // if (!Reflect.hasField (metaFields.clean, "ignore") && (command == "clean" || targetFlags.exists ("clean"))) { - if ((!Reflect.hasField(metaFields, "clean") || !Reflect.hasField(metaFields.clean, "ignore")) - && (command == "clean" - || (project.targetFlags.exists("clean") && (command == "update" || command == "build" || command == "test")))) + // if (command == "clean" || project.targetFlags.exists ("clean")) { + if (command == "clean" + || (project.targetFlags.exists("clean") && (command == "update" || command == "build" || command == "test"))) { - Log.info("", Log.accentColor + "Running command: CLEAN" + Log.resetColor); + logCommand("CLEAN"); clean(); } - if ((!Reflect.hasField(metaFields, "rebuild") || !Reflect.hasField(metaFields.rebuild, "ignore")) - && (command == "rebuild" || project.targetFlags.exists("rebuild"))) + if (command == "rebuild" || project.targetFlags.exists("rebuild")) { - Log.info("", "\n" + Log.accentColor + "Running command: REBUILD" + Log.resetColor); + logCommand("REBUILD"); // hack for now, need to move away from project.rebuild.path, probably @@ -88,60 +96,53 @@ class PlatformTarget rebuild(); } - if ((!Reflect.hasField(metaFields, "update") || !Reflect.hasField(metaFields.update, "ignore")) - && (command == "update" || command == "build" || command == "test")) + if (command == "update" || command == "build" || command == "test") { - Log.info("", "\n" + Log.accentColor + "Running command: UPDATE" + Log.resetColor); + logCommand("update"); // #if lime // AssetHelper.processLibraries (project, targetDirectory); // #end update(); } - if ((!Reflect.hasField(metaFields, "build") || !Reflect.hasField(metaFields.build, "ignore")) - && (command == "build" || command == "test")) + if (command == "build" || command == "test") { CommandHelper.executeCommands(project.preBuildCallbacks); - Log.info("", "\n" + Log.accentColor + "Running command: BUILD" + Log.resetColor); + logCommand("build"); build(); CommandHelper.executeCommands(project.postBuildCallbacks); } - if ((!Reflect.hasField(metaFields, "deploy") || !Reflect.hasField(metaFields.deploy, "ignore")) && (command == "deploy")) + if (command == "deploy") { - Log.info("", "\n" + Log.accentColor + "Running command: DEPLOY" + Log.resetColor); + logCommand("deploy"); deploy(); } - if ((!Reflect.hasField(metaFields, "install") || !Reflect.hasField(metaFields.install, "ignore")) - && (command == "install" || command == "run" || command == "test")) + if (command == "install" || command == "run" || command == "test") { - Log.info("", "\n" + Log.accentColor + "Running command: INSTALL" + Log.resetColor); + logCommand("install"); install(); } - if ((!Reflect.hasField(metaFields, "run") || !Reflect.hasField(metaFields.run, "ignore")) - && (command == "run" || command == "rerun" || command == "test")) + if (command == "run" || command == "rerun" || command == "test") { - Log.info("", "\n" + Log.accentColor + "Running command: RUN" + Log.resetColor); + logCommand("run"); run(); } - if ((!Reflect.hasField(metaFields, "trace") || !Reflect.hasField(metaFields.trace, "ignore")) - && (command == "test" || command == "trace" || command == "run" || command == "rerun")) + if ((command == "test" || command == "trace" || command == "run" || command == "rerun") + && (traceEnabled || command == "trace")) { - if (traceEnabled || command == "trace") - { - Log.info("", "\n" + Log.accentColor + "Running command: TRACE" + Log.resetColor); - this.trace(); - } + logCommand("trace"); + this.trace(); } - if ((!Reflect.hasField(metaFields, "uninstall") || !Reflect.hasField(metaFields.uninstall, "ignore")) && (command == "uninstall")) + if (command == "uninstall") { - Log.info("", "\n" + Log.accentColor + "Running command: UNINSTALL" + Log.resetColor); + logCommand("UNINSTALL"); uninstall(); } } diff --git a/src/lime/tools/ProjectHelper.hx b/src/lime/tools/ProjectHelper.hx index fa5ce214c..8bedb9a10 100644 --- a/src/lime/tools/ProjectHelper.hx +++ b/src/lime/tools/ProjectHelper.hx @@ -172,7 +172,7 @@ class ProjectHelper var object:Dynamic = project; while (object != null && fields.length > 0) { - object = Reflect.field(object, fields.shift()); + object = Reflect.getProperty(object, fields.shift()); } if (object != null && object != project) diff --git a/src/lime/tools/ProjectXMLParser.hx b/src/lime/tools/ProjectXMLParser.hx index f7bed170a..e5492e478 100644 --- a/src/lime/tools/ProjectXMLParser.hx +++ b/src/lime/tools/ProjectXMLParser.hx @@ -27,12 +27,7 @@ class ProjectXMLParser extends HXProject public function new(path:String = "", defines:Map = null, includePaths:Array = null, useExtensionPath:Bool = false) { - super(); - - if (defines != null) - { - this.defines = MapTools.copy(defines); - } + super(defines); if (includePaths != null) { @@ -43,177 +38,12 @@ class ProjectXMLParser extends HXProject this.includePaths = new Array(); } - initialize(); - if (path != "") { process(path, useExtensionPath); } } - private function initialize():Void - { - switch (platformType) - { - case MOBILE: - defines.set("platformType", "mobile"); - defines.set("mobile", "1"); - - case DESKTOP: - defines.set("platformType", "desktop"); - defines.set("desktop", "1"); - - case WEB: - defines.set("platformType", "web"); - defines.set("web", "1"); - - case CONSOLE: - defines.set("platformType", "console"); - defines.set("console", "1"); - } - - if (targetFlags.exists("neko")) - { - defines.set("targetType", "neko"); - defines.set("native", "1"); - defines.set("neko", "1"); - } - else if (targetFlags.exists("hl")) - { - defines.set("targetType", "hl"); - defines.set("native", "1"); - defines.set("hl", "1"); - if (targetFlags.exists("hlc")) - { - defines.set("hlc", "1"); - } - } - else if (targetFlags.exists("java")) - { - defines.set("targetType", "java"); - defines.set("native", "1"); - defines.set("java", "1"); - } - else if (targetFlags.exists("nodejs")) - { - defines.set("targetType", "nodejs"); - defines.set("native", "1"); - defines.set("nodejs", "1"); - } - else if (targetFlags.exists("cs")) - { - defines.set("targetType", "cs"); - defines.set("native", "1"); - defines.set("cs", "1"); - } - else if (target == Platform.FIREFOX) - { - defines.set("targetType", "js"); - defines.set("html5", "1"); - } - else if (target == Platform.AIR) - { - defines.set("targetType", "swf"); - defines.set("flash", "1"); - if (targetFlags.exists("ios")) defines.set("ios", "1"); - if (targetFlags.exists("android")) defines.set("android", "1"); - } - else if (target == Platform.WINDOWS && (targetFlags.exists("uwp") || targetFlags.exists("winjs"))) - { - targetFlags.set("uwp", ""); - targetFlags.set("winjs", ""); - - defines.set("targetType", "js"); - defines.set("html5", "1"); - defines.set("uwp", "1"); - defines.set("winjs", "1"); - } - else if (platformType == DESKTOP && target != cast System.hostPlatform) - { - defines.set("native", "1"); - - if (target == Platform.WINDOWS) - { - defines.set("targetType", "cpp"); - defines.set("cpp", "1"); - defines.set("mingw", "1"); - } - else - { - defines.set("targetType", "neko"); - defines.set("neko", "1"); - } - } - else if (target == Platform.WEB_ASSEMBLY) - { - defines.set("webassembly", "1"); - defines.set("wasm", "1"); - defines.set("emscripten", "1"); - defines.set("targetType", "cpp"); - defines.set("native", "1"); - defines.set("cpp", "1"); - } - else if (targetFlags.exists("cpp") - || ((platformType != PlatformType.WEB) && !targetFlags.exists("html5"))) - { - defines.set("targetType", "cpp"); - defines.set("native", "1"); - defines.set("cpp", "1"); - } - else if (target == Platform.FLASH) - { - defines.set("targetType", "swf"); - } - - if (debug) - { - defines.set("buildType", "debug"); - defines.set("debug", "1"); - } - else if (targetFlags.exists("final")) - { - defines.set("buildType", "final"); - defines.set("final", "1"); - } - else - { - defines.set("buildType", "release"); - defines.set("release", "1"); - } - - if (targetFlags.exists("static")) - { - defines.set("static_link", "1"); - } - - if (defines.exists("SWF_PLAYER")) - { - environment.set("SWF_PLAYER", defines.get("SWF_PLAYER")); - } - - defines.set(Std.string(target).toLowerCase(), "1"); - defines.set("target", Std.string(target).toLowerCase()); - defines.set("platform", defines.get("target")); - - switch (System.hostPlatform) - { - case WINDOWS: - defines.set("host", "windows"); - case MAC: - defines.set("host", "mac"); - case LINUX: - defines.set("host", "linux"); - default: - defines.set("host", "unknown"); - } - - #if lime - defines.set("lime-tools", "1"); - #end - - defines.set("hxp", "1"); // TODO: Version? - } - private function isValidElement(element:Access, section:String):Bool { if (element.x.get("if") != null) @@ -997,288 +827,149 @@ class ProjectXMLParser extends HXProject { for (element in xml.elements) { - var isValid = isValidElement(element, section); - if (isValid) + if (!isValidElement(element, section)) continue; + + switch (element.name) { - switch (element.name) - { - case "set": - var name = element.att.name; - var value = ""; + case "set": + var name = element.att.name; + var value = ""; - if (element.has.value) - { - value = substitute(element.att.value); - } + if (element.has.value) + { + value = substitute(element.att.value); + } - switch (name) - { - case "BUILD_DIR": app.path = value; - case "SWF_VERSION": app.swfVersion = Std.parseFloat(value); - case "PRERENDERED_ICON": config.set("ios.prerenderedIcon", value); - case "ANDROID_INSTALL_LOCATION": config.set("android.install-location", value); - } + switch (name) + { + case "BUILD_DIR": app.path = value; + case "SWF_VERSION": app.swfVersion = Std.parseFloat(value); + case "PRERENDERED_ICON": config.set("ios.prerenderedIcon", value); + case "ANDROID_INSTALL_LOCATION": config.set("android.install-location", value); + } - defines.set(name, value); - environment.set(name, value); + defines.set(name, value); + environment.set(name, value); - case "unset": - defines.remove(element.att.name); - environment.remove(element.att.name); + case "unset": + defines.remove(element.att.name); + environment.remove(element.att.name); - case "define": - var name = element.att.name; - var value = ""; + case "define": + var name = element.att.name; + var value = ""; - if (element.has.value) - { - value = substitute(element.att.value); - } + if (element.has.value) + { + value = substitute(element.att.value); + } - defines.set(name, value); - haxedefs.set(name, value); - environment.set(name, value); + defines.set(name, value); + haxedefs.set(name, value); + environment.set(name, value); - case "undefine": - defines.remove(element.att.name); - haxedefs.remove(element.att.name); - environment.remove(element.att.name); + case "undefine": + defines.remove(element.att.name); + haxedefs.remove(element.att.name); + environment.remove(element.att.name); - case "setenv": - var value = ""; + case "setenv": + var value = ""; - if (element.has.value) - { - value = substitute(element.att.value); - } - else - { - value = "1"; - } + if (element.has.value) + { + value = substitute(element.att.value); + } + else + { + value = "1"; + } - var name = substitute(element.att.name); + var name = substitute(element.att.name); - defines.set(name, value); - environment.set(name, value); - setenv(name, value); + defines.set(name, value); + environment.set(name, value); + setenv(name, value); - if (needRerun) return; + if (needRerun) return; - case "error": - Log.error(substitute(element.att.value)); + case "error": + Log.error(substitute(element.att.value)); - case "echo": - Log.println(substitute(element.att.value)); + case "echo": + Log.println(substitute(element.att.value)); - case "log": - var verbose = ""; + case "log": + var verbose = ""; - if (element.has.verbose) - { - verbose = substitute(element.att.verbose); - } + if (element.has.verbose) + { + verbose = substitute(element.att.verbose); + } - if (element.has.error) - { - Log.error(substitute(element.att.error), verbose); - } - else if (element.has.warn) - { - Log.warn(substitute(element.att.warn), verbose); - } - else if (element.has.info) - { - Log.info(substitute(element.att.info), verbose); - } - else if (element.has.value) - { - Log.info(substitute(element.att.value), verbose); - } - else if (verbose != "") - { - Log.info("", verbose); - } + if (element.has.error) + { + Log.error(substitute(element.att.error), verbose); + } + else if (element.has.warn) + { + Log.warn(substitute(element.att.warn), verbose); + } + else if (element.has.info) + { + Log.info(substitute(element.att.info), verbose); + } + else if (element.has.value) + { + Log.info(substitute(element.att.value), verbose); + } + else if (verbose != "") + { + Log.info("", verbose); + } - case "path": - var value = ""; + case "path": + var value = ""; - if (element.has.value) - { - value = substitute(element.att.value); - } - else - { - value = substitute(element.att.name); - } + if (element.has.value) + { + value = substitute(element.att.value); + } + else + { + value = substitute(element.att.name); + } - path(value); + path(value); - case "include": - var path = ""; - var addSourcePath = true; - var haxelib = null; + case "include": + var path = ""; + var addSourcePath = true; + var haxelib = null; - if (element.has.haxelib) - { - haxelib = new Haxelib(substitute(element.att.haxelib)); - path = findIncludeFile(Haxelib.getPath(haxelib, true)); - addSourcePath = false; - } - else if (element.has.path) - { - var subPath = substitute(element.att.path); - if (subPath == "") subPath = element.att.path; + if (element.has.haxelib) + { + haxelib = new Haxelib(substitute(element.att.haxelib)); + path = findIncludeFile(Haxelib.getPath(haxelib, true)); + addSourcePath = false; + } + else if (element.has.path) + { + var subPath = substitute(element.att.path); + if (subPath == "") subPath = element.att.path; - path = findIncludeFile(Path.combine(extensionPath, subPath)); - } - else - { - path = findIncludeFile(Path.combine(extensionPath, substitute(element.att.name))); - } + path = findIncludeFile(Path.combine(extensionPath, subPath)); + } + else + { + path = findIncludeFile(Path.combine(extensionPath, substitute(element.att.name))); + } - if (path != null && path != "" && FileSystem.exists(path) && !FileSystem.isDirectory(path)) - { - var includeProject = new ProjectXMLParser(path, defines); + if (path != null && path != "" && FileSystem.exists(path) && !FileSystem.isDirectory(path)) + { + var includeProject = new ProjectXMLParser(path, defines); - if (includeProject != null && haxelib != null) - { - for (ndll in includeProject.ndlls) - { - if (ndll.haxelib == null) - { - ndll.haxelib = haxelib; - } - } - } - - if (addSourcePath) - { - var dir = Path.directory(path); - - if (dir != "") - { - includeProject.sources.unshift(dir); - } - } - - merge(includeProject); - } - else if (!element.has.noerror) - { - if (path == "" || FileSystem.isDirectory(path)) - { - var errorPath = ""; - - if (element.has.path) - { - errorPath = element.att.path; - } - else if (element.has.name) - { - errorPath = element.att.name; - } - else - { - errorPath = Std.string(element); - } - - Log.error("\"" + errorPath + "\" does not appear to be a valid path"); - } - else - { - Log.error("Could not find include file \"" + path + "\""); - } - } - - case "meta": - parseMetaElement(element); - - case "app": - parseAppElement(element, extensionPath); - - case "java": - javaPaths.push(Path.combine(extensionPath, substitute(element.att.path))); - - case "language": - languages.push(element.att.name); - - case "haxelib": - if (element.has.repository) - { - setenv("HAXELIB_PATH", Path.combine(Sys.getCwd(), element.att.repository)); - if (needRerun) return; - continue; - } - - var name = substitute(element.att.name); - var version = ""; - var optional = false; - var path = null; - - if (element.has.version) - { - version = substitute(element.att.version); - } - - if (element.has.optional) - { - optional = parseBool(element.att.optional); - } - - if (element.has.path) - { - path = Path.combine(extensionPath, substitute(element.att.path)); - } - - var haxelib = new Haxelib(name, version); - - if (version != "" && defines.exists(name) && !haxelib.versionMatches(defines.get(name))) - { - Log.warn("Ignoring requested haxelib \"" + name + "\" version \"" + version + "\" (version \"" + defines.get(name) - + "\" was already included)"); - continue; - } - - if (path == null) - { - if (defines.exists("setup")) - { - path = Haxelib.getPath(haxelib); - } - else - { - path = Haxelib.getPath(haxelib, !optional); - - if (optional && path == "") - { - continue; - } - } - } - else - { - path = Path.tryFullPath(Path.combine(extensionPath, path)); - - if (version != "") - { - Haxelib.pathOverrides.set(name + ":" + version, path); - } - else - { - Haxelib.pathOverrides.set(name, path); - } - } - - if (!defines.exists(haxelib.name)) - { - defines.set(haxelib.name, Std.string(Haxelib.getVersion(haxelib))); - } - - haxelibs.push(haxelib); - - var includeProject = HXProject.fromHaxelib(haxelib, defines); - - if (includeProject != null) + if (includeProject != null && haxelib != null) { for (ndll in includeProject.ndlls) { @@ -1287,681 +978,800 @@ class ProjectXMLParser extends HXProject ndll.haxelib = haxelib; } } - - merge(includeProject); } - case "ndll": + if (addSourcePath) + { + var dir = Path.directory(path); + + if (dir != "") + { + includeProject.sources.unshift(dir); + } + } + + merge(includeProject); + } + else if (!element.has.noerror) + { + if (path == "" || FileSystem.isDirectory(path)) + { + var errorPath = ""; + + if (element.has.path) + { + errorPath = element.att.path; + } + else if (element.has.name) + { + errorPath = element.att.name; + } + else + { + errorPath = Std.string(element); + } + + Log.error("\"" + errorPath + "\" does not appear to be a valid path"); + } + else + { + Log.error("Could not find include file \"" + path + "\""); + } + } + + case "meta": + parseMetaElement(element); + + case "app": + parseAppElement(element, extensionPath); + + case "java": + javaPaths.push(Path.combine(extensionPath, substitute(element.att.path))); + + case "language": + languages.push(element.att.name); + + case "haxelib": + if (element.has.repository) + { + setenv("HAXELIB_PATH", Path.combine(Sys.getCwd(), element.att.repository)); + if (needRerun) return; + continue; + } + + var name = substitute(element.att.name); + var version = ""; + var optional = false; + var path = null; + + if (element.has.version) + { + version = substitute(element.att.version); + } + + if (element.has.optional) + { + optional = parseBool(element.att.optional); + } + + if (element.has.path) + { + path = Path.combine(extensionPath, substitute(element.att.path)); + } + + var haxelib = new Haxelib(name, version); + + if (version != "" && defines.exists(name) && !haxelib.versionMatches(defines.get(name))) + { + Log.warn("Ignoring requested haxelib \"" + name + "\" version \"" + version + "\" (version \"" + defines.get(name) + + "\" was already included)"); + continue; + } + + if (path == null) + { + if (defines.exists("setup")) + { + path = Haxelib.getPath(haxelib); + } + else + { + path = Haxelib.getPath(haxelib, !optional); + + if (optional && path == "") + { + continue; + } + } + } + else + { + path = Path.tryFullPath(Path.combine(extensionPath, path)); + + if (version != "") + { + Haxelib.pathOverrides.set(name + ":" + version, path); + } + else + { + Haxelib.pathOverrides.set(name, path); + } + } + + if (!defines.exists(haxelib.name)) + { + defines.set(haxelib.name, Std.string(Haxelib.getVersion(haxelib))); + } + + haxelibs.push(haxelib); + + var includeProject = HXProject.fromHaxelib(haxelib, defines); + + if (includeProject != null) + { + for (ndll in includeProject.ndlls) + { + if (ndll.haxelib == null) + { + ndll.haxelib = haxelib; + } + } + + merge(includeProject); + } + + case "ndll": + var name = substitute(element.att.name); + var haxelib = null; + var staticLink:Null = null; + var registerStatics = true; + var subdirectory = null; + + if (element.has.haxelib) + { + haxelib = new Haxelib(substitute(element.att.haxelib)); + } + + if (element.has.dir) + { + subdirectory = substitute(element.att.dir); + } + + if (haxelib == null && (name == "std" || name == "regexp" || name == "zlib")) + { + haxelib = new Haxelib(config.getString("cpp.buildLibrary", "hxcpp")); + } + + if (element.has.type) + { + var typeString = substitute(element.att.type).toLowerCase(); + if (typeString == "static") staticLink = true; + if (typeString == "dynamic") staticLink = false; + } + + if (element.has.register) + { + registerStatics = parseBool(element.att.register); + } + + var ndll = new NDLL(name, haxelib, staticLink, registerStatics); + ndll.extensionPath = extensionPath; + ndll.subdirectory = subdirectory; + + ndlls.push(ndll); + + case "architecture": + if (element.has.name) + { var name = substitute(element.att.name); - var haxelib = null; - var staticLink:Null = null; - var registerStatics = true; - var subdirectory = null; - if (element.has.haxelib) + if (Reflect.hasField(Architecture, name.toUpperCase())) { - haxelib = new Haxelib(substitute(element.att.haxelib)); + ArrayTools.addUnique(architectures, Reflect.field(Architecture, name.toUpperCase())); + } + } + + if (element.has.exclude) + { + var exclude = substitute(element.att.exclude); + + if (Reflect.hasField(Architecture, exclude.toUpperCase())) + { + ArrayTools.addUnique(excludeArchitectures, Reflect.field(Architecture, exclude.toUpperCase())); + } + } + + case "launchImage", "splashscreen", "splashScreen": + var path = ""; + + if (element.has.path) + { + path = Path.combine(extensionPath, substitute(element.att.path)); + } + else + { + path = Path.combine(extensionPath, substitute(element.att.name)); + } + + var splashScreen = new SplashScreen(path); + + if (element.has.width) + { + splashScreen.width = Std.parseInt(substitute(element.att.width)); + } + + if (element.has.height) + { + splashScreen.height = Std.parseInt(substitute(element.att.height)); + } + + splashScreens.push(splashScreen); + + case "launchStoryboard": + if (launchStoryboard == null) + { + launchStoryboard = new LaunchStoryboard(); + } + + if (element.has.path) + { + launchStoryboard.path = Path.combine(extensionPath, substitute(element.att.path)); + } + else if (element.has.name) + { + launchStoryboard.path = Path.combine(extensionPath, substitute(element.att.name)); + } + else if (element.has.template) + { + launchStoryboard.template = substitute(element.att.template); + launchStoryboard.templateContext = {}; + + for (attr in element.x.attributes()) + { + if (attr == "assetsPath") continue; + + var valueType = "String"; + var valueName = attr; + + if (valueName.indexOf("-") != -1) + { + valueType = valueName.substring(valueName.lastIndexOf("-") + 1); + valueName = valueName.substring(0, valueName.lastIndexOf("-")); + } + else if (valueName.indexOf(":") != -1) + { + valueType = valueName.substring(valueName.lastIndexOf(":") + 1); + valueName = valueName.substring(0, valueName.lastIndexOf(":")); + } + + var stringValue = element.x.get(attr); + var value:Dynamic; + + switch (valueType) + { + case "Int": + value = Std.parseInt(stringValue); + case "RGB": + var rgb:lime.math.ARGB = Std.parseInt(stringValue); + value = {r: rgb.r / 255, g: rgb.g / 255, b: rgb.b / 255}; + case "String": + value = stringValue; + default: + Log.warn("Ignoring unknown value type \"" + valueType + "\" in storyboard configuration."); + value = ""; + } + + Reflect.setField(launchStoryboard.templateContext, valueName, value); + } + } + + if (element.has.assetsPath) + { + launchStoryboard.assetsPath = Path.combine(extensionPath, substitute(element.att.assetsPath)); + } + + for (childElement in element.elements) + { + if (!isValidElement(childElement, "")) continue; + + switch (childElement.name) + { + case "imageset": + var name = substitute(childElement.att.name); + var imageset = new LaunchStoryboard.ImageSet(name); + + if (childElement.has.width) imageset.width = Std.parseInt(substitute(childElement.att.width)); + if (childElement.has.height) imageset.height = Std.parseInt(substitute(childElement.att.height)); + + launchStoryboard.assets.push(imageset); + } + } + + case "icon": + var path = ""; + + if (element.has.path) + { + path = Path.combine(extensionPath, substitute(element.att.path)); + } + else + { + path = Path.combine(extensionPath, substitute(element.att.name)); + } + + var icon = new Icon(path); + + if (element.has.size) + { + icon.size = icon.width = icon.height = Std.parseInt(substitute(element.att.size)); + } + + if (element.has.width) + { + icon.width = Std.parseInt(substitute(element.att.width)); + } + + if (element.has.height) + { + icon.height = Std.parseInt(substitute(element.att.height)); + } + + if (element.has.priority) + { + icon.priority = Std.parseInt(substitute(element.att.priority)); + } + + icons.push(icon); + + case "source", "classpath": + var path = ""; + + if (element.has.path) + { + path = Path.combine(extensionPath, substitute(element.att.path)); + } + else + { + path = Path.combine(extensionPath, substitute(element.att.name)); + } + + sources.push(path); + + case "extension": + + // deprecated + + case "haxedef": + if (element.has.remove) + { + haxedefs.remove(substitute(element.att.remove)); + } + else + { + var name = substitute(element.att.name); + var value = ""; + + if (element.has.value) + { + value = substitute(element.att.value); } - if (element.has.dir) + haxedefs.set(name, value); + } + + case "haxeflag", "compilerflag": + var flag = substitute(element.att.name); + + if (element.has.value) + { + flag += " " + substitute(element.att.value); + } + + haxeflags.push(substitute(flag)); + + case "window": + parseWindowElement(element); + + case "assets": + parseAssetsElement(element, extensionPath); + + case "library", "swf": + if (element.has.handler) + { + if (element.has.type) { - subdirectory = substitute(element.att.dir); + libraryHandlers.set(substitute(element.att.type), substitute(element.att.handler)); + } + } + else + { + var path = null; + var name = ""; + var type = null; + var embed:Null = null; + var preload = false; + var generate = false; + var prefix = ""; + + if (element.has.path) + { + path = Path.combine(extensionPath, substitute(element.att.path)); } - if (haxelib == null && (name == "std" || name == "regexp" || name == "zlib")) + if (element.has.name) { - haxelib = new Haxelib(config.getString("cpp.buildLibrary", "hxcpp")); + name = substitute(element.att.name); + } + + if (element.has.id) + { + name = substitute(element.att.id); } if (element.has.type) { - var typeString = substitute(element.att.type).toLowerCase(); - if (typeString == "static") staticLink = true; - if (typeString == "dynamic") staticLink = false; + type = substitute(element.att.type); } - if (element.has.register) + if (element.has.embed) { - registerStatics = parseBool(element.att.register); + embed = parseBool(element.att.embed); } - var ndll = new NDLL(name, haxelib, staticLink, registerStatics); - ndll.extensionPath = extensionPath; - ndll.subdirectory = subdirectory; - - ndlls.push(ndll); - - case "architecture": - if (element.has.name) + if (element.has.preload) { - var name = substitute(element.att.name); - - if (Reflect.hasField(Architecture, name.toUpperCase())) - { - ArrayTools.addUnique(architectures, Reflect.field(Architecture, name.toUpperCase())); - } + preload = parseBool(element.att.preload); } - if (element.has.exclude) + if (element.has.generate) { - var exclude = substitute(element.att.exclude); - - if (Reflect.hasField(Architecture, exclude.toUpperCase())) - { - ArrayTools.addUnique(excludeArchitectures, Reflect.field(Architecture, exclude.toUpperCase())); - } + generate = parseBool(element.att.generate); } - case "launchImage", "splashscreen", "splashScreen": - var path = ""; - - if (element.has.path) + if (element.has.prefix) { - path = Path.combine(extensionPath, substitute(element.att.path)); - } - else - { - path = Path.combine(extensionPath, substitute(element.att.name)); + prefix = substitute(element.att.prefix); } - var splashScreen = new SplashScreen(path); + libraries.push(new Library(path, name, type, embed, preload, generate, prefix)); + } - if (element.has.width) - { - splashScreen.width = Std.parseInt(substitute(element.att.width)); - } + case "module": + parseModuleElement(element, extensionPath); - if (element.has.height) - { - splashScreen.height = Std.parseInt(substitute(element.att.height)); - } - - splashScreens.push(splashScreen); - - case "launchStoryboard": - if (launchStoryboard == null) - { - launchStoryboard = new LaunchStoryboard(); - } - - if (element.has.path) - { - launchStoryboard.path = Path.combine(extensionPath, substitute(element.att.path)); - } - else if (element.has.name) - { - launchStoryboard.path = Path.combine(extensionPath, substitute(element.att.name)); - } - else if (element.has.template) - { - launchStoryboard.template = substitute(element.att.template); - launchStoryboard.templateContext = {}; - - for (attr in element.x.attributes()) - { - if (attr == "assetsPath") continue; - - var valueType = "String"; - var valueName = attr; - - if (valueName.indexOf("-") != -1) - { - valueType = valueName.substring(valueName.lastIndexOf("-") + 1); - valueName = valueName.substring(0, valueName.lastIndexOf("-")); - } - else if (valueName.indexOf(":") != -1) - { - valueType = valueName.substring(valueName.lastIndexOf(":") + 1); - valueName = valueName.substring(0, valueName.lastIndexOf(":")); - } - - var stringValue = element.x.get(attr); - var value:Dynamic; - - switch (valueType) - { - case "Int": - value = Std.parseInt(stringValue); - case "RGB": - var rgb:lime.math.ARGB = Std.parseInt(stringValue); - value = {r: rgb.r / 255, g: rgb.g / 255, b: rgb.b / 255}; - case "String": - value = stringValue; - default: - Log.warn("Ignoring unknown value type \"" + valueType + "\" in storyboard configuration."); - value = ""; - } - - Reflect.setField(launchStoryboard.templateContext, valueName, value); - } - } - - if (element.has.assetsPath) - { - launchStoryboard.assetsPath = Path.combine(extensionPath, substitute(element.att.assetsPath)); - } - - for (childElement in element.elements) - { - var isValid = isValidElement(childElement, ""); - - if (isValid) - { - switch (childElement.name) - { - case "imageset": - var name = substitute(childElement.att.name); - var imageset = new LaunchStoryboard.ImageSet(name); - - if (childElement.has.width) imageset.width = Std.parseInt(substitute(childElement.att.width)); - if (childElement.has.height) imageset.height = Std.parseInt(substitute(childElement.att.height)); - - launchStoryboard.assets.push(imageset); - } - } - } - - case "icon": - var path = ""; - - if (element.has.path) - { - path = Path.combine(extensionPath, substitute(element.att.path)); - } - else - { - path = Path.combine(extensionPath, substitute(element.att.name)); - } - - var icon = new Icon(path); - - if (element.has.size) - { - icon.size = icon.width = icon.height = Std.parseInt(substitute(element.att.size)); - } - - if (element.has.width) - { - icon.width = Std.parseInt(substitute(element.att.width)); - } - - if (element.has.height) - { - icon.height = Std.parseInt(substitute(element.att.height)); - } - - if (element.has.priority) - { - icon.priority = Std.parseInt(substitute(element.att.priority)); - } - - icons.push(icon); - - case "source", "classpath": - var path = ""; - - if (element.has.path) - { - path = Path.combine(extensionPath, substitute(element.att.path)); - } - else - { - path = Path.combine(extensionPath, substitute(element.att.name)); - } - - sources.push(path); - - case "extension": - - // deprecated - - case "haxedef": - if (element.has.remove) - { - haxedefs.remove(substitute(element.att.remove)); - } - else - { - var name = substitute(element.att.name); - var value = ""; - - if (element.has.value) - { - value = substitute(element.att.value); - } - - haxedefs.set(name, value); - } - - case "haxeflag", "compilerflag": - var flag = substitute(element.att.name); - - if (element.has.value) - { - flag += " " + substitute(element.att.value); - } - - haxeflags.push(substitute(flag)); - - case "window": - parseWindowElement(element); - - case "assets": - parseAssetsElement(element, extensionPath); - - case "library", "swf": - if (element.has.handler) - { - if (element.has.type) - { - libraryHandlers.set(substitute(element.att.type), substitute(element.att.handler)); - } - } - else - { - var path = null; - var name = ""; - var type = null; - var embed:Null = null; - var preload = false; - var generate = false; - var prefix = ""; - - if (element.has.path) - { - path = Path.combine(extensionPath, substitute(element.att.path)); - } - - if (element.has.name) - { - name = substitute(element.att.name); - } - - if (element.has.id) - { - name = substitute(element.att.id); - } - - if (element.has.type) - { - type = substitute(element.att.type); - } - - if (element.has.embed) - { - embed = parseBool(element.att.embed); - } - - if (element.has.preload) - { - preload = parseBool(element.att.preload); - } - - if (element.has.generate) - { - generate = parseBool(element.att.generate); - } - - if (element.has.prefix) - { - prefix = substitute(element.att.prefix); - } - - libraries.push(new Library(path, name, type, embed, preload, generate, prefix)); - } - - case "module": - parseModuleElement(element, extensionPath); - - case "ssl": + case "ssl": // if (wantSslCertificate()) // parseSsl (element); - case "sample": - samplePaths.push(Path.combine(extensionPath, substitute(element.att.path))); + case "sample": + samplePaths.push(Path.combine(extensionPath, substitute(element.att.path))); - case "target": - if (element.has.handler) + case "target": + if (element.has.handler) + { + if (element.has.name) { - if (element.has.name) - { - targetHandlers.set(substitute(element.att.name), substitute(element.att.handler)); - } + targetHandlers.set(substitute(element.att.name), substitute(element.att.handler)); } - else if (element.has.path) + } + else if (element.has.path) + { + if (element.has.name) { - if (element.has.name) - { - targetHandlers.set(substitute(element.att.name), Path.combine(extensionPath, substitute(element.att.path))); - } + targetHandlers.set(substitute(element.att.name), Path.combine(extensionPath, substitute(element.att.path))); } + } - case "template": - if (element.has.path) + case "template": + if (element.has.path) + { + if (element.has.haxelib) { - if (element.has.haxelib) - { - var haxelibPath = Haxelib.getPath(new Haxelib(substitute(element.att.haxelib)), true); - var path = Path.combine(haxelibPath, substitute(element.att.path)); - templatePaths.push(path); - } - else - { - var path = Path.combine(extensionPath, substitute(element.att.path)); - - if (FileSystem.exists(path) && !FileSystem.isDirectory(path)) - { - parseAssetsElement(element, extensionPath, true); - } - else - { - templatePaths.push(path); - } - } + var haxelibPath = Haxelib.getPath(new Haxelib(substitute(element.att.haxelib)), true); + var path = Path.combine(haxelibPath, substitute(element.att.path)); + templatePaths.push(path); } else { - parseAssetsElement(element, extensionPath, true); - } + var path = Path.combine(extensionPath, substitute(element.att.path)); - case "templatePath": - templatePaths.push(Path.combine(extensionPath, substitute(element.att.name))); - - case "preloader": - // deprecated - - app.preloader = substitute(element.att.name); - - case "output": - // deprecated - - parseOutputElement(element, extensionPath); - - case "section": - parseXML(element, "", extensionPath); - - case "certificate": - if (element.has.path || element.has.type) - { - keystore = new Keystore(); - } - - if (keystore != null) - { - if (element.has.path) + if (FileSystem.exists(path) && !FileSystem.isDirectory(path)) { - keystore.path = Path.combine(extensionPath, substitute(element.att.path)); - } - else if (element.has.keystore) - { - keystore.path = Path.combine(extensionPath, substitute(element.att.keystore)); - } - - if (element.has.type) - { - keystore.type = substitute(element.att.type); - } - - if (element.has.password) - { - keystore.password = substitute(element.att.password); - } - - if (element.has.alias) - { - keystore.alias = substitute(element.att.alias); - } - - if (element.has.resolve("alias-password")) - { - keystore.aliasPassword = substitute(element.att.resolve("alias-password")); - } - else if (element.has.alias_password) - { - keystore.aliasPassword = substitute(element.att.alias_password); - } - } - - if (element.has.identity) - { - config.set("ios.identity", element.att.identity); - config.set("tvos.identity", element.att.identity); - } - - if (element.has.resolve("team-id")) - { - config.set("ios.team-id", element.att.resolve("team-id")); - config.set("tvos.team-id", element.att.resolve("team-id")); - } - - case "dependency": - var name = ""; - var path = ""; - - if (element.has.path) - { - path = Path.combine(extensionPath, substitute(element.att.path)); - } - - if (element.has.name) - { - var foundName = substitute(element.att.name); - - if (StringTools.endsWith(foundName, ".a") || StringTools.endsWith(foundName, ".dll")) - { - path = Path.combine(extensionPath, foundName); + parseAssetsElement(element, extensionPath, true); } else { - name = foundName; + templatePaths.push(path); } } + } + else + { + parseAssetsElement(element, extensionPath, true); + } - var dependency = new Dependency(name, path); + case "templatePath": + templatePaths.push(Path.combine(extensionPath, substitute(element.att.name))); - if (element.has.embed) + case "preloader": + // deprecated + + app.preloader = substitute(element.att.name); + + case "output": + // deprecated + + parseOutputElement(element, extensionPath); + + case "section": + parseXML(element, "", extensionPath); + + case "certificate": + if (element.has.path || element.has.type) + { + keystore = new Keystore(); + } + + if (keystore != null) + { + if (element.has.path) { - dependency.embed = parseBool(element.att.embed); + keystore.path = Path.combine(extensionPath, substitute(element.att.path)); } - - if (element.has.resolve("force-load")) + else if (element.has.keystore) { - dependency.forceLoad = parseBool(element.att.resolve("force-load")); + keystore.path = Path.combine(extensionPath, substitute(element.att.keystore)); } - if (element.has.resolve("web-worker")) + if (element.has.type) { - dependency.webWorker = parseBool(element.att.resolve("web-worker")); + keystore.type = substitute(element.att.type); } - var i = dependencies.length; - - while (i-- > 0) + if (element.has.password) { - if ((name != "" && dependencies[i].name == name) || (path != "" && dependencies[i].path == path)) - { - dependencies.splice(i, 1); - } + keystore.password = substitute(element.att.password); } - dependencies.push(dependency); - - case "android": - // deprecated - - for (attribute in element.x.attributes()) + if (element.has.alias) { - var name = attribute; - var value = substitute(element.att.resolve(attribute)); - - switch (name) - { - case "minimum-sdk-version": - config.set("android.minimum-sdk-version", Std.parseInt(value)); - - case "target-sdk-version": - config.set("android.target-sdk-version", Std.parseInt(value)); - - case "install-location": - config.set("android.install-location", value); - - case "extension": - var extensions = config.getArrayString("android.extension"); - - if (extensions == null || extensions.indexOf(value) == -1) - { - config.push("android.extension", value); - } - - case "permission": - var permissions = config.getArrayString("android.permission"); - - if (permissions == null || permissions.indexOf(value) == -1) - { - config.push("android.permission", value); - } - - case "gradle-version": - config.set("android.gradle-version", value); - - default: - name = formatAttributeName(attribute); - } + keystore.alias = substitute(element.att.alias); } - case "cpp": - // deprecated - - for (attribute in element.x.attributes()) + if (element.has.resolve("alias-password")) { - var name = attribute; - var value = substitute(element.att.resolve(attribute)); - - switch (name) - { - case "build-library": - config.set("cpp.buildLibrary", value); - - default: - name = formatAttributeName(attribute); - } + keystore.aliasPassword = substitute(element.att.resolve("alias-password")); } - - case "ios": - // deprecated - - if (target == Platform.IOS) + else if (element.has.alias_password) { - if (element.has.deployment) - { - var deployment = Std.parseFloat(substitute(element.att.deployment)); - - // If it is specified, assume the dev knows what he is doing! - config.set("ios.deployment", deployment); - } - - if (element.has.binaries) - { - var binaries = substitute(element.att.binaries); - - switch (binaries) - { - case "fat": - ArrayTools.addUnique(architectures, Architecture.ARMV6); - ArrayTools.addUnique(architectures, Architecture.ARMV7); - - case "armv6": - ArrayTools.addUnique(architectures, Architecture.ARMV6); - architectures.remove(Architecture.ARMV7); - - case "armv7": - ArrayTools.addUnique(architectures, Architecture.ARMV7); - architectures.remove(Architecture.ARMV6); - } - } - - if (element.has.devices) - { - config.set("ios.device", substitute(element.att.devices).toLowerCase()); - } - - if (element.has.compiler) - { - config.set("ios.compiler", substitute(element.att.compiler)); - } - - if (element.has.resolve("prerendered-icon")) - { - config.set("ios.prerenderedIcon", substitute(element.att.resolve("prerendered-icon"))); - } - - if (element.has.resolve("linker-flags")) - { - config.push("ios.linker-flags", substitute(element.att.resolve("linker-flags"))); - } + keystore.aliasPassword = substitute(element.att.alias_password); } + } - case "tvos": - // deprecated + if (element.has.identity) + { + config.set("ios.identity", element.att.identity); + config.set("tvos.identity", element.att.identity); + } - if (target == Platform.TVOS) + if (element.has.resolve("team-id")) + { + config.set("ios.team-id", element.att.resolve("team-id")); + config.set("tvos.team-id", element.att.resolve("team-id")); + } + + case "dependency": + var name = ""; + var path = ""; + + if (element.has.path) + { + path = Path.combine(extensionPath, substitute(element.att.path)); + } + + if (element.has.name) + { + var foundName = substitute(element.att.name); + + if (StringTools.endsWith(foundName, ".a") || StringTools.endsWith(foundName, ".dll")) { - if (element.has.deployment) - { - var deployment = Std.parseFloat(substitute(element.att.deployment)); - - // If it is specified, assume the dev knows what he is doing! - config.set("tvos.deployment", deployment); - } - - if (element.has.binaries) - { - var binaries = substitute(element.att.binaries); - - switch (binaries) - { - case "arm64": - ArrayTools.addUnique(architectures, Architecture.ARM64); - } - } - - if (element.has.devices) - { - config.set("tvos.device", substitute(element.att.devices).toLowerCase()); - } - - if (element.has.compiler) - { - config.set("tvos.compiler", substitute(element.att.compiler)); - } - - if (element.has.resolve("prerendered-icon")) - { - config.set("tvos.prerenderedIcon", substitute(element.att.resolve("prerendered-icon"))); - } - - if (element.has.resolve("linker-flags")) - { - config.push("tvos.linker-flags", substitute(element.att.resolve("linker-flags"))); - } + path = Path.combine(extensionPath, foundName); } + else + { + name = foundName; + } + } - case "config": + var dependency = new Dependency(name, path); + + if (element.has.embed) + { + dependency.embed = parseBool(element.att.embed); + } + + if (element.has.resolve("force-load")) + { + dependency.forceLoad = parseBool(element.att.resolve("force-load")); + } + + if (element.has.resolve("web-worker")) + { + dependency.webWorker = parseBool(element.att.resolve("web-worker")); + } + + var i = dependencies.length; + + while (i-- > 0) + { + if ((name != "" && dependencies[i].name == name) || (path != "" && dependencies[i].path == path)) + { + dependencies.splice(i, 1); + } + } + + dependencies.push(dependency); + + case "android": + // deprecated + + for (attribute in element.x.attributes()) + { + var name = attribute; + var value = substitute(element.att.resolve(attribute)); + + switch (name) + { + case "minimum-sdk-version": + config.set("android.minimum-sdk-version", Std.parseInt(value)); + + case "target-sdk-version": + config.set("android.target-sdk-version", Std.parseInt(value)); + + case "install-location": + config.set("android.install-location", value); + + case "extension", "permission": + config.push("android." + name, value, true); + + case "gradle-version": + config.set("android.gradle-version", value); + + default: + name = formatAttributeName(attribute); + } + } + + case "cpp": + // deprecated + + for (attribute in element.x.attributes()) + { + var name = attribute; + var value = substitute(element.att.resolve(attribute)); + + switch (name) + { + case "build-library": + config.set("cpp.buildLibrary", value); + + default: + name = formatAttributeName(attribute); + } + } + + case "ios": + // deprecated + + if (target != Platform.IOS) continue; + + if (element.has.deployment) + { + var deployment = Std.parseFloat(substitute(element.att.deployment)); + + // If it is specified, assume the dev knows what he is doing! + config.set("ios.deployment", deployment); + } + + if (element.has.binaries) + { + var binaries = substitute(element.att.binaries); + + switch (binaries) + { + case "fat": + ArrayTools.addUnique(architectures, Architecture.ARMV6); + ArrayTools.addUnique(architectures, Architecture.ARMV7); + + case "armv6": + ArrayTools.addUnique(architectures, Architecture.ARMV6); + architectures.remove(Architecture.ARMV7); + + case "armv7": + ArrayTools.addUnique(architectures, Architecture.ARMV7); + architectures.remove(Architecture.ARMV6); + } + } + + if (element.has.devices) + { + config.set("ios.device", substitute(element.att.devices).toLowerCase()); + } + + if (element.has.compiler) + { + config.set("ios.compiler", substitute(element.att.compiler)); + } + + if (element.has.resolve("prerendered-icon")) + { + config.set("ios.prerenderedIcon", substitute(element.att.resolve("prerendered-icon"))); + } + + if (element.has.resolve("linker-flags")) + { + config.push("ios.linker-flags", substitute(element.att.resolve("linker-flags"))); + } + + case "tvos": + // deprecated + + if (target != Platform.TVOS) continue; + + if (element.has.deployment) + { + var deployment = Std.parseFloat(substitute(element.att.deployment)); + + // If it is specified, assume the dev knows what he is doing! + config.set("tvos.deployment", deployment); + } + + if (element.has.binaries) + { + var binaries = substitute(element.att.binaries); + + switch (binaries) + { + case "arm64": + ArrayTools.addUnique(architectures, Architecture.ARM64); + } + } + + if (element.has.devices) + { + config.set("tvos.device", substitute(element.att.devices).toLowerCase()); + } + + if (element.has.compiler) + { + config.set("tvos.compiler", substitute(element.att.compiler)); + } + + if (element.has.resolve("prerendered-icon")) + { + config.set("tvos.prerenderedIcon", substitute(element.att.resolve("prerendered-icon"))); + } + + if (element.has.resolve("linker-flags")) + { + config.push("tvos.linker-flags", substitute(element.att.resolve("linker-flags"))); + } + + case "config": + config.parse(element, substitute); + + case "prebuild": + parseCommandElement(element, preBuildCallbacks); + + case "postbuild": + parseCommandElement(element, postBuildCallbacks); + + default: + if (StringTools.startsWith(element.name, "config:")) + { config.parse(element, substitute); - - case "prebuild": - parseCommandElement(element, preBuildCallbacks); - - case "postbuild": - parseCommandElement(element, postBuildCallbacks); - - default: - if (StringTools.startsWith(element.name, "config:")) - { - config.parse(element, substitute); - } - } + } } } } diff --git a/src/lime/ui/FileDialog.hx b/src/lime/ui/FileDialog.hx index 0720afd78..e179d2114 100644 --- a/src/lime/ui/FileDialog.hx +++ b/src/lime/ui/FileDialog.hx @@ -5,6 +5,7 @@ import haxe.io.Path; import lime._internal.backend.native.NativeCFFI; import lime.app.Event; import lime.graphics.Image; +import lime.system.CFFI; import lime.system.ThreadPool; import lime.utils.ArrayBuffer; import lime.utils.Resource; @@ -147,15 +148,7 @@ class FileDialog var path = null; #if (!macro && lime_cffi) - #if hl - var bytes = NativeCFFI.lime_file_dialog_open_file(title, filter, defaultPath); - if (bytes != null) - { - path = @:privateAccess String.fromUTF8(cast bytes); - } - #else - path = NativeCFFI.lime_file_dialog_open_file(title, filter, defaultPath); - #end + path = CFFI.stringValue(NativeCFFI.lime_file_dialog_open_file(title, filter, defaultPath)); #end worker.sendComplete(path); @@ -174,7 +167,7 @@ class FileDialog paths = []; for (i in 0...bytes.length) { - paths[i] = @:privateAccess String.fromUTF8(bytes[i]); + paths[i] = CFFI.stringValue(bytes[i]); } } #else @@ -191,15 +184,7 @@ class FileDialog var path = null; #if (!macro && lime_cffi) - #if hl - var bytes = NativeCFFI.lime_file_dialog_open_directory(title, filter, defaultPath); - if (bytes != null) - { - path = @:privateAccess String.fromUTF8(cast bytes); - } - #else - path = NativeCFFI.lime_file_dialog_open_directory(title, filter, defaultPath); - #end + path = CFFI.stringValue(NativeCFFI.lime_file_dialog_open_directory(title, filter, defaultPath)); #end worker.sendComplete(path); @@ -211,15 +196,7 @@ class FileDialog var path = null; #if (!macro && lime_cffi) - #if hl - var bytes = NativeCFFI.lime_file_dialog_save_file(title, filter, defaultPath); - if (bytes != null) - { - path = @:privateAccess String.fromUTF8(cast bytes); - } - #else - path = NativeCFFI.lime_file_dialog_save_file(title, filter, defaultPath); - #end + path = CFFI.stringValue(NativeCFFI.lime_file_dialog_save_file(title, filter, defaultPath)); #end worker.sendComplete(path); @@ -273,12 +250,7 @@ class FileDialog var path = null; #if (!macro && lime_cffi) - #if hl - var bytes = NativeCFFI.lime_file_dialog_open_file(title, filter, defaultPath); - if (bytes != null) path = @:privateAccess String.fromUTF8(cast bytes); - #else - path = NativeCFFI.lime_file_dialog_open_file(title, filter, defaultPath); - #end + path = CFFI.stringValue(NativeCFFI.lime_file_dialog_open_file(title, filter, defaultPath)); #end worker.sendComplete(path); @@ -341,12 +313,7 @@ class FileDialog var path = null; #if (!macro && lime_cffi) - #if hl - var bytes = NativeCFFI.lime_file_dialog_save_file(title, filter, defaultPath); - path = @:privateAccess String.fromUTF8(cast bytes); - #else - path = NativeCFFI.lime_file_dialog_save_file(title, filter, defaultPath); - #end + path = CFFI.stringValue(NativeCFFI.lime_file_dialog_save_file(title, filter, defaultPath)); #end worker.sendComplete(path); diff --git a/src/lime/ui/Gamepad.hx b/src/lime/ui/Gamepad.hx index 9dbbf2c1e..f2b424fcc 100644 --- a/src/lime/ui/Gamepad.hx +++ b/src/lime/ui/Gamepad.hx @@ -2,6 +2,7 @@ package lime.ui; import lime._internal.backend.native.NativeCFFI; import lime.app.Event; +import lime.system.CFFI; #if !lime_debug @:fileXml('tags="haxe,release"') @@ -64,11 +65,7 @@ class Gamepad @:noCompletion private inline function get_guid():String { #if (lime_cffi && !macro) - #if hl - return @:privateAccess String.fromUTF8(NativeCFFI.lime_gamepad_get_device_guid(this.id)); - #else - return NativeCFFI.lime_gamepad_get_device_guid(this.id); - #end + return CFFI.stringValue(NativeCFFI.lime_gamepad_get_device_guid(this.id)); #elseif (js && html5) var devices = Joystick.__getDeviceData(); return devices[this.id].id; @@ -80,11 +77,7 @@ class Gamepad @:noCompletion private inline function get_name():String { #if (lime_cffi && !macro) - #if hl - return @:privateAccess String.fromUTF8(NativeCFFI.lime_gamepad_get_device_name(this.id)); - #else - return NativeCFFI.lime_gamepad_get_device_name(this.id); - #end + return CFFI.stringValue(NativeCFFI.lime_gamepad_get_device_name(this.id)); #elseif (js && html5) var devices = Joystick.__getDeviceData(); return devices[this.id].id; diff --git a/src/lime/ui/Joystick.hx b/src/lime/ui/Joystick.hx index 2215c8d17..3f23c2a9e 100644 --- a/src/lime/ui/Joystick.hx +++ b/src/lime/ui/Joystick.hx @@ -2,6 +2,7 @@ package lime.ui; import lime._internal.backend.native.NativeCFFI; import lime.app.Event; +import lime.system.CFFI; #if !lime_debug @:fileXml('tags="haxe,release"') @@ -53,8 +54,19 @@ class Joystick #if (js && html5) @:noCompletion private static function __getDeviceData():Array { - return - (untyped navigator.getGamepads) ? untyped navigator.getGamepads() : (untyped navigator.webkitGetGamepads) ? untyped navigator.webkitGetGamepads() : null; + var res:Dynamic = null; + + try + { + res = (untyped navigator.getGamepads) ? untyped navigator.getGamepads() : (untyped navigator.webkitGetGamepads) ? untyped navigator.webkitGetGamepads() : null; + } + catch (err:Dynamic) + { + // if something went wrong, treat it the same as when navigator.getGamepads doesn't exist + // we probably don't have permission to use this feature + } + + return res; } #end @@ -62,11 +74,7 @@ class Joystick @:noCompletion private inline function get_guid():String { #if (lime_cffi && !macro) - #if hl - return @:privateAccess String.fromUTF8(NativeCFFI.lime_joystick_get_device_guid(this.id)); - #else - return NativeCFFI.lime_joystick_get_device_guid(this.id); - #end + return CFFI.stringValue(NativeCFFI.lime_joystick_get_device_guid(this.id)); #elseif (js && html5) var devices = __getDeviceData(); return devices[this.id].id; @@ -78,11 +86,7 @@ class Joystick @:noCompletion private inline function get_name():String { #if (lime_cffi && !macro) - #if hl - return @:privateAccess String.fromUTF8(NativeCFFI.lime_joystick_get_device_name(this.id)); - #else - return NativeCFFI.lime_joystick_get_device_name(this.id); - #end + return CFFI.stringValue(NativeCFFI.lime_joystick_get_device_name(this.id)); #elseif (js && html5) var devices = __getDeviceData(); return devices[this.id].id; diff --git a/src/lime/utils/Float32Array.hx b/src/lime/utils/Float32Array.hx index 4a29c4552..6f3876b65 100644 --- a/src/lime/utils/Float32Array.hx +++ b/src/lime/utils/Float32Array.hx @@ -93,7 +93,6 @@ import lime.utils.ArrayBufferView; abstract Float32Array(ArrayBufferView) from ArrayBufferView to ArrayBufferView { public inline static var BYTES_PER_ELEMENT:Int = 4; - public static var hello:Int; public var length(get, never):Int; diff --git a/templates/android/template/app/src/main/AndroidManifest.xml b/templates/android/template/app/src/main/AndroidManifest.xml index af4261bf9..501db19f7 100644 --- a/templates/android/template/app/src/main/AndroidManifest.xml +++ b/templates/android/template/app/src/main/AndroidManifest.xml @@ -4,20 +4,18 @@ - ::if (ANDROID_PERMISSIONS != null)::::foreach ANDROID_PERMISSIONS:: - ::end::::end:: + ::foreach ANDROID_PERMISSIONS:: + ::end:: - =30):: android:allowNativeHeapPointerTagging="false" ::end::> + ::if (WIN_ORIENTATION=="portrait"):: - + + ::elseif (WIN_ORIENTATION=="landscape"):: + ::end:: - ::if (WIN_ORIENTATION=="landscape"):: - - ::end:: - - + diff --git a/tools/CommandLineTools.hx b/tools/CommandLineTools.hx index da14a8d40..857c3555b 100644 --- a/tools/CommandLineTools.hx +++ b/tools/CommandLineTools.hx @@ -231,31 +231,31 @@ class CommandLineTools switch (targetName) { case "cpp": - target = cast System.hostPlatform; + target = System.hostPlatform; targetFlags.set("cpp", ""); case "neko": - target = cast System.hostPlatform; + target = System.hostPlatform; targetFlags.set("neko", ""); case "hl", "hashlink": - target = cast System.hostPlatform; + target = System.hostPlatform; targetFlags.set("hl", ""); case "cppia": - target = cast System.hostPlatform; + target = System.hostPlatform; targetFlags.set("cppia", ""); case "java": - target = cast System.hostPlatform; + target = System.hostPlatform; targetFlags.set("java", ""); case "nodejs": - target = cast System.hostPlatform; + target = System.hostPlatform; targetFlags.set("nodejs", ""); case "cs": - target = cast System.hostPlatform; + target = System.hostPlatform; targetFlags.set("cs", ""); case "iphone", "iphoneos": @@ -1513,15 +1513,15 @@ class CommandLineTools switch (targetName) { case "cpp": - target = cast System.hostPlatform; + target = System.hostPlatform; targetFlags.set("cpp", ""); case "neko": - target = cast System.hostPlatform; + target = System.hostPlatform; targetFlags.set("neko", ""); case "hl", "hashlink": - target = cast System.hostPlatform; + target = System.hostPlatform; targetFlags.set("hl", ""); case "hlc": @@ -1530,19 +1530,19 @@ class CommandLineTools targetFlags.set("hlc", ""); case "cppia": - target = cast System.hostPlatform; + target = System.hostPlatform; targetFlags.set("cppia", ""); case "java": - target = cast System.hostPlatform; + target = System.hostPlatform; targetFlags.set("java", ""); case "nodejs": - target = cast System.hostPlatform; + target = System.hostPlatform; targetFlags.set("nodejs", ""); case "cs": - target = cast System.hostPlatform; + target = System.hostPlatform; targetFlags.set("cs", ""); case "iphone", "iphoneos": @@ -1727,6 +1727,11 @@ class CommandLineTools return null; } } + + if (project != null) + { + project.projectFilePath = projectFile; + } } if (project != null && project.needRerun && !project.targetFlags.exists("norerun")) diff --git a/tools/platforms/AIRPlatform.hx b/tools/platforms/AIRPlatform.hx index 93d14d052..1cc7e7155 100644 --- a/tools/platforms/AIRPlatform.hx +++ b/tools/platforms/AIRPlatform.hx @@ -120,7 +120,7 @@ class AIRPlatform extends FlashPlatform } else { - targetPlatform = cast System.hostPlatform; + targetPlatform = System.hostPlatform; targetPlatformType = DESKTOP; } } diff --git a/tools/platforms/AndroidPlatform.hx b/tools/platforms/AndroidPlatform.hx index 2509e2b89..1e864f778 100644 --- a/tools/platforms/AndroidPlatform.hx +++ b/tools/platforms/AndroidPlatform.hx @@ -294,7 +294,12 @@ class AndroidPlatform extends PlatformTarget { var path = targetDirectory + "/haxe/" + buildType + ".hxml"; - if (FileSystem.exists(path)) + // try to use the existing .hxml file. however, if the project file was + // modified more recently than the .hxml, then the .hxml cannot be + // considered valid anymore. it may cause errors in editors like vscode. + if (FileSystem.exists(path) + && (project.projectFilePath == null || !FileSystem.exists(project.projectFilePath) + || (FileSystem.stat(path).mtime.getTime() > FileSystem.stat(project.projectFilePath).mtime.getTime()))) { return File.getContent(path); } @@ -464,7 +469,21 @@ class AndroidPlatform extends PlatformTarget context.ANDROID_USE_ANDROIDX = project.config.getString("android.useAndroidX", "true"); context.ANDROID_ENABLE_JETIFIER = project.config.getString("android.enableJetifier", "false"); - context.ANDROID_LIBRARY_PROJECTS = []; + context.ANDROID_APPLICATION = project.config.getKeyValueArray("android.application", { + "android:label": project.meta.title, + "android:allowBackup": "true", + "android:theme": "@android:style/Theme.NoTitleBar" + (project.window.fullscreen ? ".Fullscreen" : null), + "android:hardwareAccelerated": "true", + "android:allowNativeHeapPointerTagging": context.ANDROID_TARGET_SDK_VERSION >= 30 ? "false" : null + }); + context.ANDROID_ACTIVITY = project.config.getKeyValueArray("android.activity", { + "android:name": "MainActivity", + "android:exported": "true", + "android:launchMode": "singleTask", + "android:label": project.meta.title, + "android:configChanges": project.config.getArrayString("android.configChanges", ["keyboardHidden", "orientation", "screenSize", "screenLayout", "uiMode"]).join("|"), + "android:screenOrientation": project.window.orientation == PORTRAIT ? "sensorPortrait" : (project.window.orientation == LANDSCAPE ? "sensorLandscape" : null) + }); if (!project.environment.exists("ANDROID_SDK") || !project.environment.exists("ANDROID_NDK_ROOT")) { @@ -490,9 +509,8 @@ class AndroidPlatform extends PlatformTarget context.ANDROID_BUILD_TOOLS_VERSION = AndroidHelper.getBuildToolsVersion(project); } - var escaped = ~/([ #!=\\:])/g; - context.ANDROID_SDK_ESCAPED = escaped.replace(context.ENV_ANDROID_SDK, "\\$1"); - context.ANDROID_NDK_ROOT_ESCAPED = escaped.replace(context.ENV_ANDROID_NDK_ROOT, "\\$1"); + context.ANDROID_SDK_ESCAPED = StringTools.replace(context.ENV_ANDROID_SDK, "\\", "\\\\"); + context.ANDROID_NDK_ROOT_ESCAPED = StringTools.replace(context.ENV_ANDROID_NDK_ROOT, "\\", "\\\\"); if (Reflect.hasField(context, "KEY_STORE")) context.KEY_STORE = StringTools.replace(context.KEY_STORE, "\\", "\\\\"); if (Reflect.hasField(context, "KEY_STORE_ALIAS")) context.KEY_STORE_ALIAS = StringTools.replace(context.KEY_STORE_ALIAS, "\\", "\\\\"); @@ -501,6 +519,7 @@ class AndroidPlatform extends PlatformTarget "KEY_STORE_ALIAS_PASSWORD")) context.KEY_STORE_ALIAS_PASSWORD = StringTools.replace(context.KEY_STORE_ALIAS_PASSWORD, "\\", "\\\\"); var index = 1; + context.ANDROID_LIBRARY_PROJECTS = []; for (dependency in project.dependencies) { @@ -524,24 +543,38 @@ class AndroidPlatform extends PlatformTarget } } - var iconTypes = ["ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"]; - var iconSizes = [36, 48, 72, 96, 144, 192]; - var icons = project.icons; - - if (icons.length == 0) + for (attribute in context.ANDROID_APPLICATION) { - icons = [new Icon(System.findTemplate(project.templatePaths, "default/icon.svg"))]; - } - - for (i in 0...iconTypes.length) - { - if (IconHelper.createIcon(icons, iconSizes[i], iconSizes[i], sourceSet + "/res/drawable-" + iconTypes[i] + "/icon.png")) + if (attribute.key == "android:icon") { context.HAS_ICON = true; + break; } } - IconHelper.createIcon(icons, 732, 412, sourceSet + "/res/drawable-xhdpi/ouya_icon.png"); + if (context.HAS_ICON == null) + { + var iconTypes = ["ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"]; + var iconSizes = [36, 48, 72, 96, 144, 192]; + var icons = project.icons; + + if (icons.length == 0) + { + icons = [new Icon(System.findTemplate(project.templatePaths, "default/icon.svg"))]; + } + for (i in 0...iconTypes.length) + { + // create multiple icons, only set "android:icon" once + if (IconHelper.createIcon(icons, iconSizes[i], iconSizes[i], sourceSet + "/res/drawable-" + iconTypes[i] + "/icon.png") + && !context.HAS_ICON) + { + context.HAS_ICON = true; + context.ANDROID_APPLICATION.push({ key: "android:icon", value: "@drawable/icon" }); + } + } + + IconHelper.createIcon(icons, 732, 412, sourceSet + "/res/drawable-xhdpi/ouya_icon.png"); + } var packageDirectory = project.meta.packageName; packageDirectory = sourceSet + "/java/" + packageDirectory.split(".").join("/"); diff --git a/tools/platforms/FlashPlatform.hx b/tools/platforms/FlashPlatform.hx index 19b4812d5..21828d2a3 100644 --- a/tools/platforms/FlashPlatform.hx +++ b/tools/platforms/FlashPlatform.hx @@ -174,7 +174,12 @@ class FlashPlatform extends PlatformTarget { var path = targetDirectory + "/haxe/" + buildType + ".hxml"; - if (FileSystem.exists(path)) + // try to use the existing .hxml file. however, if the project file was + // modified more recently than the .hxml, then the .hxml cannot be + // considered valid anymore. it may cause errors in editors like vscode. + if (FileSystem.exists(path) + && (project.projectFilePath == null || !FileSystem.exists(project.projectFilePath) + || (FileSystem.stat(path).mtime.getTime() > FileSystem.stat(project.projectFilePath).mtime.getTime()))) { return File.getContent(path); } diff --git a/tools/platforms/HTML5Platform.hx b/tools/platforms/HTML5Platform.hx index 97198ebf4..94d8a45f2 100644 --- a/tools/platforms/HTML5Platform.hx +++ b/tools/platforms/HTML5Platform.hx @@ -213,7 +213,12 @@ class HTML5Platform extends PlatformTarget { var path = targetDirectory + "/haxe/" + buildType + ".hxml"; - if (FileSystem.exists(path)) + // try to use the existing .hxml file. however, if the project file was + // modified more recently than the .hxml, then the .hxml cannot be + // considered valid anymore. it may cause errors in editors like vscode. + if (FileSystem.exists(path) + && (project.projectFilePath == null || !FileSystem.exists(project.projectFilePath) + || (FileSystem.stat(path).mtime.getTime() > FileSystem.stat(project.projectFilePath).mtime.getTime()))) { return File.getContent(path); } diff --git a/tools/platforms/IOSPlatform.hx b/tools/platforms/IOSPlatform.hx index e03754c3a..33197d9a3 100644 --- a/tools/platforms/IOSPlatform.hx +++ b/tools/platforms/IOSPlatform.hx @@ -456,7 +456,12 @@ class IOSPlatform extends PlatformTarget { var path = targetDirectory + "/" + project.app.file + "/haxe/Build.hxml"; - if (FileSystem.exists(path)) + // try to use the existing .hxml file. however, if the project file was + // modified more recently than the .hxml, then the .hxml cannot be + // considered valid anymore. it may cause errors in editors like vscode. + if (FileSystem.exists(path) + && (project.projectFilePath == null || !FileSystem.exists(project.projectFilePath) + || (FileSystem.stat(path).mtime.getTime() > FileSystem.stat(project.projectFilePath).mtime.getTime()))) { return File.getContent(path); } diff --git a/tools/platforms/LinuxPlatform.hx b/tools/platforms/LinuxPlatform.hx index 1686dee32..33a402915 100644 --- a/tools/platforms/LinuxPlatform.hx +++ b/tools/platforms/LinuxPlatform.hx @@ -138,7 +138,7 @@ class LinuxPlatform extends PlatformTarget is64 = targetFlags.exists("64"); } - if (project.targetFlags.exists("neko") || project.target != cast System.hostPlatform) + if (project.targetFlags.exists("neko") || project.target != System.hostPlatform) { targetType = "neko"; } @@ -380,7 +380,12 @@ class LinuxPlatform extends PlatformTarget { var path = targetDirectory + "/haxe/" + buildType + ".hxml"; - if (FileSystem.exists(path)) + // try to use the existing .hxml file. however, if the project file was + // modified more recently than the .hxml, then the .hxml cannot be + // considered valid anymore. it may cause errors in editors like vscode. + if (FileSystem.exists(path) + && (project.projectFilePath == null || !FileSystem.exists(project.projectFilePath) + || (FileSystem.stat(path).mtime.getTime() > FileSystem.stat(project.projectFilePath).mtime.getTime()))) { return File.getContent(path); } @@ -485,7 +490,7 @@ class LinuxPlatform extends PlatformTarget { System.runCommand(applicationDirectory, "java", ["-jar", project.app.file + ".jar"].concat(arguments)); } - else if (project.target == cast System.hostPlatform) + else if (project.target == System.hostPlatform) { arguments = arguments.concat(["-livereload"]); System.runCommand(applicationDirectory, "./" + Path.withoutDirectory(executablePath), arguments); diff --git a/tools/platforms/MacPlatform.hx b/tools/platforms/MacPlatform.hx index bbf359a81..7d690f180 100644 --- a/tools/platforms/MacPlatform.hx +++ b/tools/platforms/MacPlatform.hx @@ -130,7 +130,7 @@ class MacPlatform extends PlatformTarget } } - if (project.targetFlags.exists("neko") || project.target != cast System.hostPlatform) + if (project.targetFlags.exists("neko") || project.target != System.hostPlatform) { targetType = "neko"; } @@ -382,7 +382,12 @@ class MacPlatform extends PlatformTarget { var path = targetDirectory + "/haxe/" + buildType + ".hxml"; - if (FileSystem.exists(path)) + // try to use the existing .hxml file. however, if the project file was + // modified more recently than the .hxml, then the .hxml cannot be + // considered valid anymore. it may cause errors in editors like vscode. + if (FileSystem.exists(path) + && (project.projectFilePath == null || !FileSystem.exists(project.projectFilePath) + || (FileSystem.stat(path).mtime.getTime() > FileSystem.stat(project.projectFilePath).mtime.getTime()))) { return File.getContent(path); } @@ -456,7 +461,7 @@ class MacPlatform extends PlatformTarget { System.runCommand(executableDirectory, "java", ["-jar", project.app.file + ".jar"].concat(arguments)); } - else if (project.target == cast System.hostPlatform) + else if (project.target == System.hostPlatform) { arguments = arguments.concat(["-livereload"]); System.runCommand(executableDirectory, "./" + Path.withoutDirectory(executablePath), arguments); diff --git a/tools/platforms/TVOSPlatform.hx b/tools/platforms/TVOSPlatform.hx index 54aae23b7..e0273b3b3 100644 --- a/tools/platforms/TVOSPlatform.hx +++ b/tools/platforms/TVOSPlatform.hx @@ -371,7 +371,12 @@ class TVOSPlatform extends PlatformTarget { var path = targetDirectory + "/" + project.app.file + "/haxe/Build.hxml"; - if (FileSystem.exists(path)) + // try to use the existing .hxml file. however, if the project file was + // modified more recently than the .hxml, then the .hxml cannot be + // considered valid anymore. it may cause errors in editors like vscode. + if (FileSystem.exists(path) + && (project.projectFilePath == null || !FileSystem.exists(project.projectFilePath) + || (FileSystem.stat(path).mtime.getTime() > FileSystem.stat(project.projectFilePath).mtime.getTime()))) { return File.getContent(path); } diff --git a/tools/platforms/WebAssemblyPlatform.hx b/tools/platforms/WebAssemblyPlatform.hx index 69fbdb2f2..a8130365c 100644 --- a/tools/platforms/WebAssemblyPlatform.hx +++ b/tools/platforms/WebAssemblyPlatform.hx @@ -359,7 +359,12 @@ class WebAssemblyPlatform extends PlatformTarget { var path = targetDirectory + "/haxe/" + buildType + ".hxml"; - if (FileSystem.exists(path)) + // try to use the existing .hxml file. however, if the project file was + // modified more recently than the .hxml, then the .hxml cannot be + // considered valid anymore. it may cause errors in editors like vscode. + if (FileSystem.exists(path) + && (project.projectFilePath == null || !FileSystem.exists(project.projectFilePath) + || (FileSystem.stat(path).mtime.getTime() > FileSystem.stat(project.projectFilePath).mtime.getTime()))) { return File.getContent(path); } diff --git a/tools/platforms/WindowsPlatform.hx b/tools/platforms/WindowsPlatform.hx index b5f4fc9cc..b2851043b 100644 --- a/tools/platforms/WindowsPlatform.hx +++ b/tools/platforms/WindowsPlatform.hx @@ -138,7 +138,7 @@ class WindowsPlatform extends PlatformTarget { targetType = "winjs"; } - else if (project.targetFlags.exists("neko") || project.target != cast System.hostPlatform) + else if (project.targetFlags.exists("neko")) { targetType = "neko"; } @@ -557,6 +557,24 @@ class WindowsPlatform extends PlatformTarget CPPHelper.compile(project, targetDirectory + "/obj", flags); System.copyFile(targetDirectory + "/obj/ApplicationMain" + (project.debug ? "-debug" : "") + ".exe", executablePath); + + if (project.targetFlags.exists("mingw")) + { + var libraries = ["libwinpthread-1.dll", "libstdc++-6.dll"]; + if (is64) + { + libraries.push("libgcc_s_seh-1.dll"); + } + else + { + libraries.push("libgcc_s_dw2-1.dll"); + } + + for (library in libraries) + { + System.copyIfNewer(targetDirectory + "/obj/" + library, Path.combine(applicationDirectory, library)); + } + } } else { @@ -654,7 +672,12 @@ class WindowsPlatform extends PlatformTarget { var path = targetDirectory + "/haxe/" + buildType + ".hxml"; - if (FileSystem.exists(path)) + // try to use the existing .hxml file. however, if the project file was + // modified more recently than the .hxml, then the .hxml cannot be + // considered valid anymore. it may cause errors in editors like vscode. + if (FileSystem.exists(path) + && (project.projectFilePath == null || !FileSystem.exists(project.projectFilePath) + || (FileSystem.stat(path).mtime.getTime() > FileSystem.stat(project.projectFilePath).mtime.getTime()))) { return File.getContent(path); } @@ -851,7 +874,7 @@ class WindowsPlatform extends PlatformTarget { winrtRun(arguments); } - else if (project.target == cast System.hostPlatform) + else if (project.target == System.hostPlatform) { arguments = arguments.concat(["-livereload"]); System.runCommand(applicationDirectory, Path.withoutDirectory(executablePath), arguments); diff --git a/tools/utils/PlatformSetup.hx b/tools/utils/PlatformSetup.hx index 8f7c6be91..93d84cf6c 100644 --- a/tools/utils/PlatformSetup.hx +++ b/tools/utils/PlatformSetup.hx @@ -816,89 +816,92 @@ class PlatformSetup setupHaxelib(new Haxelib("lime")); } - var haxePath = Sys.getEnv("HAXEPATH"); - - if (System.hostPlatform == WINDOWS) + if (!targetFlags.exists("noalias")) { - if (haxePath == null || haxePath == "") - { - haxePath = "C:\\HaxeToolkit\\haxe\\"; - } + var haxePath = Sys.getEnv("HAXEPATH"); - try + if (System.hostPlatform == WINDOWS) { - File.copy(Haxelib.getPath(new Haxelib("lime")) + "\\templates\\\\bin\\lime.exe", haxePath + "\\lime.exe"); - } - catch (e:Dynamic) {} - try - { - File.copy(Haxelib.getPath(new Haxelib("lime")) + "\\templates\\\\bin\\lime.sh", haxePath + "\\lime"); - } - catch (e:Dynamic) {} - } - else - { - if (haxePath == null || haxePath == "") - { - haxePath = "/usr/lib/haxe"; - } + if (haxePath == null || haxePath == "") + { + haxePath = "C:\\HaxeToolkit\\haxe\\"; + } - var installedCommand = false; - var answer = YES; - - if (targetFlags.exists("y")) - { - Sys.println("Do you want to install the \"lime\" command? [y/n/a] y"); + try + { + File.copy(Haxelib.getPath(new Haxelib("lime")) + "\\templates\\\\bin\\lime.exe", haxePath + "\\lime.exe"); + } + catch (e:Dynamic) {} + try + { + File.copy(Haxelib.getPath(new Haxelib("lime")) + "\\templates\\\\bin\\lime.sh", haxePath + "\\lime"); + } + catch (e:Dynamic) {} } else { - answer = CLIHelper.ask("Do you want to install the \"lime\" command?"); - } - - if (answer == YES || answer == ALWAYS) - { - if (System.hostPlatform == MAC) + if (haxePath == null || haxePath == "") { - try - { - System.runCommand("", "cp", [ - "-f", - Haxelib.getPath(new Haxelib("lime")) + "/templates/bin/lime.sh", - "/usr/local/bin/lime" - ], false); - System.runCommand("", "chmod", ["755", "/usr/local/bin/lime"], false); - installedCommand = true; - } - catch (e:Dynamic) {} + haxePath = "/usr/lib/haxe"; + } + + var installedCommand = false; + var answer = YES; + + if (targetFlags.exists("y")) + { + Sys.println("Do you want to install the \"lime\" command? [y/n/a] y"); } else { - try - { - System.runCommand("", "sudo", [ - "cp", - "-f", - Haxelib.getPath(new Haxelib("lime")) + "/templates/bin/lime.sh", - "/usr/local/bin/lime" - ], false); - System.runCommand("", "sudo", ["chmod", "755", "/usr/local/bin/lime"], false); - installedCommand = true; - } - catch (e:Dynamic) {} + answer = CLIHelper.ask("Do you want to install the \"lime\" command?"); } - } - if (!installedCommand) - { - Sys.println(""); - Sys.println("To finish setup, we recommend you either..."); - Sys.println(""); - Sys.println(" a) Manually add an alias called \"lime\" to run \"haxelib run lime\""); - Sys.println(" b) Run the following commands:"); - Sys.println(""); - Sys.println("sudo cp \"" + Path.combine(Haxelib.getPath(new Haxelib("lime")), "templates/bin/lime.sh") + "\" /usr/local/bin/lime"); - Sys.println("sudo chmod 755 /usr/local/bin/lime"); - Sys.println(""); + if (answer == YES || answer == ALWAYS) + { + if (System.hostPlatform == MAC) + { + try + { + System.runCommand("", "cp", [ + "-f", + Haxelib.getPath(new Haxelib("lime")) + "/templates/bin/lime.sh", + "/usr/local/bin/lime" + ], false); + System.runCommand("", "chmod", ["755", "/usr/local/bin/lime"], false); + installedCommand = true; + } + catch (e:Dynamic) {} + } + else + { + try + { + System.runCommand("", "sudo", [ + "cp", + "-f", + Haxelib.getPath(new Haxelib("lime")) + "/templates/bin/lime.sh", + "/usr/local/bin/lime" + ], false); + System.runCommand("", "sudo", ["chmod", "755", "/usr/local/bin/lime"], false); + installedCommand = true; + } + catch (e:Dynamic) {} + } + } + + if (!installedCommand) + { + Sys.println(""); + Sys.println("To finish setup, we recommend you either..."); + Sys.println(""); + Sys.println(" a) Manually add an alias called \"lime\" to run \"haxelib run lime\""); + Sys.println(" b) Run the following commands:"); + Sys.println(""); + Sys.println("sudo cp \"" + Path.combine(Haxelib.getPath(new Haxelib("lime")), "templates/bin/lime.sh") + "\" /usr/local/bin/lime"); + Sys.println("sudo chmod 755 /usr/local/bin/lime"); + Sys.println(""); + } } } @@ -1036,114 +1039,121 @@ class PlatformSetup setupHaxelib(new Haxelib("openfl")); } - var haxePath = Sys.getEnv("HAXEPATH"); - var project = null; - - try + if (!targetFlags.exists("noalias")) { - project = HXProject.fromHaxelib(new Haxelib("openfl")); - } - catch (e:Dynamic) {} - - if (System.hostPlatform == WINDOWS) - { - if (haxePath == null || haxePath == "") - { - haxePath = "C:\\HaxeToolkit\\haxe\\"; - } + var haxePath = Sys.getEnv("HAXEPATH"); + var project = null; try { - File.copy(Haxelib.getPath(new Haxelib("lime")) + "\\templates\\\\bin\\lime.exe", haxePath + "\\lime.exe"); - } - catch (e:Dynamic) {} - try - { - File.copy(Haxelib.getPath(new Haxelib("lime")) + "\\templates\\\\bin\\lime.sh", haxePath + "\\lime"); + project = HXProject.fromHaxelib(new Haxelib("openfl")); } catch (e:Dynamic) {} - try + if (System.hostPlatform == WINDOWS) { - System.copyFileTemplate(project.templatePaths, "bin/openfl.exe", haxePath + "\\openfl.exe"); - System.copyFileTemplate(project.templatePaths, "bin/openfl.sh", haxePath + "\\openfl"); - } - catch (e:Dynamic) {} - } - else - { - if (haxePath == null || haxePath == "") - { - haxePath = "/usr/lib/haxe"; - } + if (haxePath == null || haxePath == "") + { + haxePath = "C:\\HaxeToolkit\\haxe\\"; + } - var installedCommand = false; - var answer = YES; + try + { + File.copy(Haxelib.getPath(new Haxelib("lime")) + "\\templates\\\\bin\\lime.exe", haxePath + "\\lime.exe"); + } + catch (e:Dynamic) {} + try + { + File.copy(Haxelib.getPath(new Haxelib("lime")) + "\\templates\\\\bin\\lime.sh", haxePath + "\\lime"); + } + catch (e:Dynamic) {} - if (targetFlags.exists("y")) - { - Sys.println("Do you want to install the \"openfl\" command? [y/n/a] y"); + try + { + System.copyFileTemplate(project.templatePaths, "bin/openfl.exe", haxePath + "\\openfl.exe"); + System.copyFileTemplate(project.templatePaths, "bin/openfl.sh", haxePath + "\\openfl"); + } + catch (e:Dynamic) {} } else { - answer = CLIHelper.ask("Do you want to install the \"openfl\" command?"); - } - - if (answer == YES || answer == ALWAYS) - { - if (System.hostPlatform == MAC) + if (haxePath == null || haxePath == "") { - try - { - System.runCommand("", "cp", [ - "-f", - Haxelib.getPath(new Haxelib("lime")) + "/templates/bin/lime.sh", - "/usr/local/bin/lime" - ], false); - System.runCommand("", "chmod", ["755", "/usr/local/bin/lime"], false); - System.runCommand("", "cp", [ - "-f", - System.findTemplate(project.templatePaths, "bin/openfl.sh"), - "/usr/local/bin/openfl" - ], false); - System.runCommand("", "chmod", ["755", "/usr/local/bin/openfl"], false); - installedCommand = true; - } - catch (e:Dynamic) {} + haxePath = "/usr/lib/haxe"; + } + + var installedCommand = false; + var answer = YES; + + if (targetFlags.exists("y")) + { + Sys.println("Do you want to install the \"openfl\" command? [y/n/a] y"); } else { - System.runCommand("", "sudo", [ - "cp", - "-f", - Haxelib.getPath(new Haxelib("lime")) + "/templates/bin/lime.sh", - "/usr/local/bin/lime" - ], false); - System.runCommand("", "sudo", ["chmod", "755", "/usr/local/bin/lime"], false); - System.runCommand("", "sudo", [ - "cp", - "-f", - System.findTemplate(project.templatePaths, "bin/openfl.sh"), - "/usr/local/bin/openfl" - ], false); - System.runCommand("", "sudo", ["chmod", "755", "/usr/local/bin/openfl"], false); - installedCommand = true; + answer = CLIHelper.ask("Do you want to install the \"openfl\" command?"); } - } - if (!installedCommand) - { - Sys.println(""); - Sys.println("To finish setup, we recommend you either..."); - Sys.println(""); - Sys.println(" a) Manually add an alias called \"openfl\" to run \"haxelib run openfl\""); - Sys.println(" b) Run the following commands:"); - Sys.println(""); - Sys.println("sudo cp \"" + Path.combine(Haxelib.getPath(new Haxelib("lime")), "templates/bin/lime.sh") + "\" /usr/local/bin/lime"); - Sys.println("sudo chmod 755 /usr/local/bin/lime"); - Sys.println("sudo cp \"" + System.findTemplate(project.templatePaths, "bin/openfl.sh") + "\" /usr/local/bin/openfl"); - Sys.println("sudo chmod 755 /usr/local/bin/openfl"); - Sys.println(""); + if (answer == YES || answer == ALWAYS) + { + if (System.hostPlatform == MAC) + { + try + { + System.runCommand("", "cp", [ + "-f", + Haxelib.getPath(new Haxelib("lime")) + "/templates/bin/lime.sh", + "/usr/local/bin/lime" + ], false); + System.runCommand("", "chmod", ["755", "/usr/local/bin/lime"], false); + System.runCommand("", "cp", [ + "-f", + System.findTemplate(project.templatePaths, "bin/openfl.sh"), + "/usr/local/bin/openfl" + ], false); + System.runCommand("", "chmod", ["755", "/usr/local/bin/openfl"], false); + installedCommand = true; + } + catch (e:Dynamic) {} + } + else + { + try + { + System.runCommand("", "sudo", [ + "cp", + "-f", + Haxelib.getPath(new Haxelib("lime")) + "/templates/bin/lime.sh", + "/usr/local/bin/lime" + ], false); + System.runCommand("", "sudo", ["chmod", "755", "/usr/local/bin/lime"], false); + System.runCommand("", "sudo", [ + "cp", + "-f", + System.findTemplate(project.templatePaths, "bin/openfl.sh"), + "/usr/local/bin/openfl" + ], false); + System.runCommand("", "sudo", ["chmod", "755", "/usr/local/bin/openfl"], false); + installedCommand = true; + } + catch (e:Dynamic) {} + } + } + + if (!installedCommand) + { + Sys.println(""); + Sys.println("To finish setup, we recommend you either..."); + Sys.println(""); + Sys.println(" a) Manually add an alias called \"openfl\" to run \"haxelib run openfl\""); + Sys.println(" b) Run the following commands:"); + Sys.println(""); + Sys.println("sudo cp \"" + Path.combine(Haxelib.getPath(new Haxelib("lime")), "templates/bin/lime.sh") + "\" /usr/local/bin/lime"); + Sys.println("sudo chmod 755 /usr/local/bin/lime"); + Sys.println("sudo cp \"" + System.findTemplate(project.templatePaths, "bin/openfl.sh") + "\" /usr/local/bin/openfl"); + Sys.println("sudo chmod 755 /usr/local/bin/openfl"); + Sys.println(""); + } } }