GWT HTML export from LibGdx shows : GwtApplication: exception: (TypeError) - html

I have an Android game developed with LibGdx version 1.9.9, which I am trying to export in HTML. I am using GWT (V-2.8.2). The game is running well in Android and doesn't have any issues. While exporting the game by running this command ./gradlew html:dist I am not getting any errors.
But when I am placing the exported library into the localhost and trying to access the game, first the default loader is appearing and then there is a blank screen with this error message:
GwtApplication: exception: (TypeError) : null is not an object (evaluating 'null.zY')
(TypeError) : null is not an object (evaluating 'null.zY')
This is happening in every browser - Safari, Chrome, Firefox.
The stack trace doesn't show any significant place of debug.
Any idea of what is the problem? Thanks.
HTML Gradle:
gwt {
gwtVersion='2.8.0' // Should match the gwt version used for building the gwt backend
maxHeapSize="2G" // Default 256m is not enough for gwt compiler. GWT is HUNGRY
minHeapSize="1G"
src = files(file("src/")) // Needs to be in front of "modules" below.
modules 'com.package.gamename.GdxDefinition'
devModules 'com.package.gamename.GdxDefinitionSuperdev'
project.webAppDirName = 'webapp'
compiler {
strict = true;
disableCastChecking = true;
}
}
import org.wisepersist.gradle.plugins.gwt.GwtSuperDev
def HttpFileServer server = null
def httpFilePort = 8080
task startHttpServer () {
dependsOn draftCompileGwt
String output = project.buildDir.path + "/gwt/draftOut"
doLast {
copy {
from "webapp"
into output
}
copy {
from "war"
into output
}
server = new SimpleHttpFileServerFactory().start(new File(output), httpFilePort)
println "Server started in directory " + server.getContentRoot() + ", http://localhost:" + server.getPort()
}
}
task superDev (type: GwtSuperDev) {
dependsOn startHttpServer
doFirst {
gwt.modules = gwt.devModules
}
}
task dist(dependsOn: [clean, compileGwt]) {
doLast {
file("build/dist").mkdirs()
copy {
from "build/gwt/out"
into "build/dist"
}
copy {
from "webapp"
into "build/dist"
}
copy {
from "war"
into "build/dist"
}
}
}
task addSource {
doLast {
sourceSets.main.compileClasspath += files(project(':core').sourceSets.main.allJava.srcDirs)
}
}
tasks.compileGwt.dependsOn(addSource)
tasks.draftCompileGwt.dependsOn(addSource)
sourceCompatibility = 1.6
sourceSets.main.java.srcDirs = [ "src/" ]
eclipse.project {
name = appName + "-html"
}

Enter the superdev mode and activate source mapping and debugging and step through the source in Chrome, that's the way to find these problems.
Start with superdev parameter
Open the game's web page
Hit the arrow button at the top left corner
Hit the "compile" button
Source Maps are available in Chrome now, you get a "real" stack trace.

Related

Enforce Microsoft.Build to reload the project

I'm trying to iteratively (part of automation):
Create backup of the projects in solution (physical files on the filesystem)
Using Microsoft.Build programmatically load and change projects inside of the solution (refernces, includes, some other properties)
Build it with console call of msbuild
Restore projects (physically overriding patched versions from backups)
This approach works well for first iteration, but for second it appears that it does not load restored projects and trying to work with values that I patched on the first iteration. It looks like projects are cached: inside of the csproj files I see correct values, but on the code I see previously patched values.
My best guess is that Microsoft.Build is caching solution/projects in the context of the current process.
Here is code that is responsible to load project and call method to update project information:
private static void ForEachProject(string slnPath, Func<ProjectRootElement> patchProject)
{
SolutionFile slnFile = SolutionFile.Parse(slnPath);
var filtredProjects = slnFile
.ProjectsInOrder
.Where(prj => prj.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat);
foreach (ProjectInSolution projectInfo in filtredProjects)
{
try
{
ProjectRootElement project = ProjectRootElement.Open(projectInfo.AbsolutePath);
patchProject(project);
project.Save();
}
catch (InvalidProjectFileException ex)
{
Console.WriteLine("Failed to patch project '{0}' with error: {1}", projectInfo.AbsolutePath, ex);
}
}
}
There is Reload method for the ProjectRootElement that migh be called before iteraction with content of the project.
It will enforce Microsoft.Build to read latest information from the file.
Code that is working for me:
private static void ForEachProject(string slnPath, Func<ProjectRootElement> patchProject)
{
SolutionFile slnFile = SolutionFile.Parse(slnPath);
var filtredProjects = slnFile
.ProjectsInOrder
.Where(prj => prj.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat);
foreach (ProjectInSolution projectInfo in filtredProjects)
{
try
{
ProjectRootElement project = ProjectRootElement.Open(projectInfo.AbsolutePath);
project.Reload(false); // Ignore cached state, read actual from the file
patchProject(project);
project.Save();
}
catch (InvalidProjectFileException ex)
{
Console.WriteLine("Failed to patch project '{0}' with error: {1}", projectInfo.AbsolutePath, ex);
}
}
}
Note: It better to use custom properties inside of the project and provide it for each msbuild call instead of physical project patching. Please consider it as better solution and use it if possible.

Sencha 6 EXT JS Build using CMD - wrong paths

Sencha 6.2 CMD
Sencha EXT JS GPL 6+
My web structure [server side]
-/public_html/affiliates
--/app/sprinkles/tracker/assets/sencha [workspace folder - containing ext in /ext]
--/app/sprinkles/tracker/assets/sencha/affiliates - contains sencha app
From Web Side [browser]
App is called when at http://localhost/affiliates
Path to app is http://localhost/assets-raw/tracker/assets/sencha/affiliates
Note: http://localhost/assets-raw/tracker/assets/sencha/affiliates/index.html
Works no issue!
When i goto http://localhost/affiliates
I'm getting 404 errors for ext/classic (maybe 50ish js can't load)
Also app/application.js can't load
I need to be able to add ../assets-raw/tracker/assets/sencha/affiliates to just the production build path.
However I'm finding that distinquishing paths webside to build path side is difficult. Cannot find the sencha doc that would discuss this (i've gone thru the docs alot)
Here is my app.json config
https://gist.github.com/bobby5892/bf607a37c79a62820cf7fcaa245553c4
workspace.json config
https://gist.github.com/bobby5892/689c54272ba49d63cb35b96f6a24266d
How i initialize extjs on the page
<script type="text/javascript">
var Ext = Ext || {}; // Ext namespace won't be defined yet...
// This function is called by the Microloader after it has performed basic
// device detection. The results are provided in the "tags" object. You can
// use these tags here or even add custom tags. These can be used by platform
// filters in your manifest or by platformConfig expressions in your app.
//
Ext.manifest = '../assets-raw/tracker/assets/sencha/affiliates/classic';
</script>
<!-- The line below must be kept intact for Sencha Cmd to build your application -->
<script id="microloader" data-app="48a1b848-93ab-47fe-ba5a-a54e94f92ae5" type="text/javascript" src="/assets-raw/tracker/assets/sencha/affiliates/bootstrap.js"></script>
How do i edit that path?
Here is the relevant part from app.json (included in that gist)
"production": {
"frameworks": {
"ext": {
"path":"../assets-raw/tracker/assets/sencha/ext",
"version":"6.2.0.981"
}
},
"output":
{
"base": "${workspace.build.dir}/${build.environment}/${app.name}",
"page": "../assets-raw/tracker/assets/sencha/affiliates/index.html",
"manifest": "../assets-raw/tracker/assets/sencha/affiliates/${build.id}.json",
"js": "../assets-raw/tracker/assets/sencha/affiliates/${build.id}/app.js",
"appCache": {
"enable": false
},
"resources": {
"path": "${build.id}/resources",
"shared": "resources"
}
},
"loader": {
"cache": "${build.timestamp}"
},
"cache": {
"enable": false
},
"compressor": {
"type": "yui"
},
"manifest": {
"embed": true
}
also i'm doing the build via sencha cmd
sencha app refresh
sencha app build
Thanks in advance, have put alot of time into trying to figure this out!
Edit: Adding image to show the paths that are vs the paths I need.
Paths
Edit: Have found that when sencha CMD is generating the build, the generated paths in classic.json are wrong. The documentation says changing the output parameter in app.json for "page" might work. I have that in the the "production" segment of the build. Still not working. :(
Results in discussion on sencha forum yielded success.
https://www.sencha.com/forum/showthread.php?469231-Sencha-6-EXT-JS-Build-using-CMD-wrong-paths
Solved by changing the paths in the Ext.Manifest object after retrieved from ajax call but prior to them being processed by ExtJS.
<script type="text/javascript">
ExtAbsoluteBasePath = "/assets-raw/tracker/assets/sencha/build/production/affiliates/";
var Ext = Ext || {}; // Ext namespace won't be defined yet...
// This function is called by the Microloader after it has performed basic
// device detection. The results are provided in the "tags" object. You can
// use these tags here or even add custom tags. These can be used by platform
// filters in your manifest or by platformConfig expressions in your app.
//
Ext.beforeLoad = function (tags) {
var s = location.search, // the query string (ex "?foo=1&bar")
profile;
// For testing look for "?classic" or "?modern" in the URL to override
// device detection default.
//
if (s.match(/\bclassic\b/)) {
profile = 'classic';
}
else if (s.match(/\bmodern\b/)) {
profile = 'modern';
}
else {
profile = tags.desktop ? 'classic' : 'modern';
//profile = tags.phone ? 'modern' : 'classic';
}
Ext.manifest = ExtAbsoluteBasePath + profile; // this name must match a build profile name
// This function is called once the manifest is available but before
// any data is pulled from it.
//
return function (manifest) {
// peek at / modify the manifest object
console.log(manifest);
// Update JS Paths
var i=0;
manifest.js.forEach(function(jsPath) {
console.log("\n Updating JS Path - " + jsPath.assetConfig.path + " to " + ExtAbsoluteBasePath + jsPath.assetConfig.path);
manifest.js[i].assetConfig.path = ExtAbsoluteBasePath + jsPath.assetConfig.path;
i++;
});
// Update CSS Paths
i=0;
manifest.css.forEach(function(cssPath) {
console.log("\n Updating CSS Path - " + cssPath.assetConfig.path + " to " + ExtAbsoluteBasePath + cssPath.assetConfig.path);
manifest.css[i].assetConfig.path = ExtAbsoluteBasePath + cssPath.assetConfig.path;
i++;
});
//manifest.js["0"].assetConfig.path = ExtAbsoluteBasePath + manifest.js["0"].assetConfig.path;
console.log("\n JS Path - " + manifest.js["0"].assetConfig.path);
};
};
</script>

Why does my texture packer not find the sprites?

Im using the TexturePacker implemented by LibGDX to load my sprites.
For some reason however, the files are not found and it gives me this exception:
Exception in thread "main" java.lang.RuntimeException: Error packing images.
at com.badlogic.gdx.tools.texturepacker.TexturePacker.process(TexturePacker.java:620)
at com.zebleck.OneRoom.desktop.DesktopLauncher.processSprites(DesktopLauncher.java:35)
at com.zebleck.OneRoom.desktop.DesktopLauncher.main(DesktopLauncher.java:17)
Caused by: java.lang.IllegalArgumentException: Input file does not exist: C:\Users\Kontor\Desktop\Codeporn\LibGDX-workspace\OneRoom\desktop\sprites\input
at com.badlogic.gdx.tools.FileProcessor.process(FileProcessor.java:117)
at com.badlogic.gdx.tools.texturepacker.TexturePackerFileProcessor.process(TexturePackerFileProcessor.java:70)
at com.badlogic.gdx.tools.texturepacker.TexturePacker.process(TexturePacker.java:618)
... 2 more
This code is causing the error:
public static void main (String[] arg) {
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
config.width = 800;
config.height = 800;
deleteFiles();
processSprites();
new LwjglApplication(new OneRoom(), config);
}
public static void deleteFiles() {
File outputDir = new File("../android/assets/sprites/output");
File[] listFiles = outputDir.listFiles();
if (listFiles != null && listFiles.length > 0) {
for (File file : listFiles) {
file.delete();
}
}
}
public static void processSprites() {
TexturePacker.Settings settings = new TexturePacker.Settings();
//System.out.println(Gdx.files.internal("sprites/input/player.png").toString());
TexturePacker.process(settings, "sprites/input", "sprites/output", "pack"); // THIS LINE CAUSES THE ERROR
}
I also got the EXACT same code in another project and it works just fine. I haven't found any differences in the project properties yet.
Make sure the sprites actually exist in that directory.
Sounds patronising but I was having the same issue and for me I was being misled by my assets directory in my desktop project being a "Linked Folder" that was actually just a reference to the assets folder of my core project. So in eclipse the folder is there and looks like there should be no problem but looking through windows file explorer it was clear the files didn't actually exist at that location.
My fix was to change the input and output to step back and check the core directory instead of the desktop.
So instead of:
TexturePacker.process(settings, "sprites/input", "sprites/output", "pack");
The following would work:
TexturePacker.process(settings, "../core/sprites/input", "../core/sprites/output", "pack");
Now I don't know your exact setup but considering your code works in a different project I would wager that the other project has the assets actually stored in the desktop directory where as this one stores the images in the core directory.

Issue with CDialog::DoModal() when called from firebreath plugin

I have my ActiveX COM component developed in VC6. I have created the firebreath plugin over it to be able to call the COM API from different browsers. I have one API in ActiveX component which pops up the CDialog UI, On Google Chrome browser dlg.DoModal() function is failing. Issue is only with Chrome it simply crashes at this call, in other browsers its working perfectly
On Windows 7 its working with Google Chrome as well issue is with Windows XP.
Please provide me some feedback on this issue.
I am attaching some code snippets here to give some idea of what I am trying to do
Firebreath Plugin code (Plugin name is FBTest):
bool FBTest::onWindowAttached(FB::AttachedEvent *evt, FB::PluginWindow *piw)
{
// The window is attached; act appropriately
try {
/* Now that we have the plugin window, create the ActiveX container
window as a child of the plugin, then create the ActiveX control
as a child of the container.
*/
FB::PluginWindowWin* pwnd = piw->get_as<FB::PluginWindowWin>();
if(pwnd != NULL)
{
HWND hWnd = pwnd->getHWND();
if(hWnd)
{
// Create the ActiveX control container
RECT rc;
::GetClientRect(hWnd, &rc);
m_fbTestWin.Create(hWnd, &rc, 0, WS_VISIBLE|WS_CHILD);
CComPtr<IUnknown> spControlTest;
//ETESTPROGID is prog id of activex component
HRESULT hrTest = m_fbTestWin.CreateControlEx(ETESTPROGID, NULL, NULL, &spControlTest, GUID_NULL, NULL);
if(SUCCEEDED(hrTest) && (spControlTest != NULL))
{
spControlTest.QueryInterface(&m_eTestAxCtl);
g_eTestAxCtl = m_eTestAxCtl;
if (m_eTestAxCtl)
{
//TODO: should we throw a FB exception here?
}
}
}
}
} catch(...) {
//TODO: should we throw a FB exception here?
}
return false;
}
void FBTest::TestFunc()
{
//hThread = (HANDLE)_beginthreadex(NULL, 0,&FBTest::Start, (void*)&m_eTestAxCtl, 0, &ThreadId);
if(m_eTestAxCtl)
{
try {
long nCode = -1;
//This is call to API of Activex component which will popup the dialog
HRESULT hr = m_eTestAxCtl->TestFunc();
//return nCode;
}
catch(...) {
}
}
}
Activex Component code :
STDMETHODIMP CTest::TestFunc()
{
//CTestDlg is ATL Dialog Object
CTestDlg TestDlg;
//At this call Google chrome is crashing
if(!TestDlg.DoModal())
return S_FALSE;
return S_OK;
}
I am calling TestFunc() API of plugin from one HTML page and its showing me the dailog in IE and firefox browsers but Chrome is crashing..
Please help.
Since you've given no info on when or how you're calling it, it's hard to be sure, but my guess is that you're calling DoModal on the main thread. That will cause the main thread to block.
You must never block the main thread in a plugin.
Try calling it on a different thread.

Cordova multiple callbacks in Windows Phone 8

I have a Cordova plugin which works fine for both Android & iOS. However, it fails when ported to Windows Phone 8 because it seems that multiple outstanding callbacks are not supported in Cordova for Windows Phone.
The problem is this:
When a DispatchCommandResult is called with a PluginResult which has KeepCallback set to true, a further DispatchCommand from a different method will call both its callback and the previous callback (the one with KeepCallback set to true).
Worse still, if the second DispatchCommandResult has a PluginResult which has KeepCallback set to false (the default) then this cancels any further callbacks which have KeepCallback set to true.
Example:
Consider the code below. It's a modification of the Cordova Echo sample.
The echo method will (via DispatchCommandResult) call the javascript 'success' callback with the same string which it was originally called with (after a couple of JSON conversions)
The repeat method does the same as echo except it repeatedly calls the javascript 'success' callback every 5 seconds in a separate thread.
If repeat is called and then at some point after echo is called, the DispatchCommandResult in the echo method will result in both the echo success and the repeat success callbacks being called and then prevent further repeat success callbacks because the KeepCallback was not set to true.
In Android this problem is not an issue because of the callbackId provided by Cordova. However, for Windows Phone, the callbackId is not accessible.
C# code
namespace Cordova.Extension.Commands
{
public class Echo : BaseCommand
{
public void echo(string options)
{
string optVal = JsonHelper.Deserialize<string[]>(options)[0];
DispatchCommandResult(new PluginResult(PluginResult.Status.OK, optVal));
}
public void repeat(string options)
{
string optVal = JsonHelper.Deserialize<string[]>(options)[0];
ThreadStart worker = () =>
{
try
{
while (true)
{
Thread.Sleep(5000);
PluginResult r = new PluginResult(PluginResult.Status.OK, optVal);
r.KeepCallback = true;
DispatchCommandResult(r);
}
}
catch (Exception ex)
{
this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ex.Message));
}
};
new Thread(worker).Start();
}
}
}
JavaScript code
function echo() {
function success(message) {
console.log("echo success: " + message);
}
function error(e) {
console.log("echo error: " + e);
}
cordova.exec(success, error, "Echo", "echo", ["Hello"]);
}
function repeat() {
function success(message) {
console.log("repeat success: " + message);
}
function error(e) {
console.log("repeat error: " + e);
}
cordova.exec(success, error, "Echo", "repeat", ["Hello again"]);
}
echo();
.
.
.
repeat();
.
.
.
echo();
Sample output
Log:"echo success: Hello"
Log:"repeat success: Hello again"
Log:"repeat success: Hello again"
Log:"repeat success: Hello again"
Log:"repeat success: Hello again"
Log:"repeat success: Hello"
Log:"echo success: Hello"
Has anyone else had this problem? If so, is there a workaround? Am I doing anything wrong?
I had the same problem with cordova 2.5 and this is what I found.
In the (not yet released) 2.8 version of cordova, if you look at the BaseCommand.cs of the cordovalib files. You can see a CurrentCommandCallbackId that can be used to keep track of the callback you want to call.
Then if you set the KeepCallback to false, you can dispatch the command to the wanted callback.
The current release of PhoneGap is the 2.7.0, so to use this you'll have to clone the 2.8 version of cordova and copy the content of Plugins, cordova and cordivalib of the templates/standalone folder.
Once done, you can use this new feature with something like:
private void DispatchMessage(PluginResult.Status status, string message, bool keepCallback, string callBackID)
{
PluginResult res = new PluginResult(status, message);
res.KeepCallback = keepCallback;
DispatchCommandResult(res, callBackID);
}
However, once Phonegap 2.8 will be release, it will be safer to update your App with an official version of Cordova.