I am working on a Pebble watch face and I ran into a problem, the function app_message_outbox_send seems to throw an error (which then crashes my app). The error is "[INFO ] E call_internal.c:36 syscall failure! 0..0x8 is not in app space."
The relevant code:
static void askPhoneForCharge(){
if(bluetooth_connection_service_peek()){
DictionaryIterator *iter;
app_message_outbox_begin(&iter);
dict_write_uint8(iter, KEY_PHONE_ASK, 0);
app_message_outbox_send();
}else{
phoneCharging = 0;
phoneCharge = 0;
updatePhoneBattery();
}
}
Here is how I set up the handlers and open the channel:
app_message_register_inbox_received(inboxReceivedCallback);
app_message_register_inbox_dropped(inboxDroppedCallback);
app_message_register_outbox_failed(outboxFailedCallback);
app_message_register_outbox_sent(outboxSentCallback);
app_message_open(app_message_inbox_size_maximum(), app_message_outbox_size_maximum());
As it turns out, you can not use the message functions while in the initialization phase, so I started a timer that only executes once to take care of the initial messaging.
I was having the same problem while sending the app_message_outbox_send() command which was getting called by to the Up_button_click handler.
The following initialization code in the Init() method fixed it for me.
Look at the "Register message handlers" & "Init buffers"
void out_sent_handler(DictionaryIterator *sent, void *context){}
static void out_fail_handler(DictionaryIterator *failed, AppMessageResult reason, void* context){}
static void in_received_handler(DictionaryIterator *iter, void* context){}
void in_drop_handler(AppMessageResult reason, void *context){}
static void init() {
// Register message handlers
app_message_register_outbox_sent(out_sent_handler);
app_message_register_inbox_received(in_received_handler);
app_message_register_inbox_dropped(in_drop_handler);
app_message_register_outbox_failed(out_fail_handler);
// Init buffers
app_message_open(64, 64);
// Create main Window element and assign to pointer
s_main_window = window_create();
// Set handlers to manage the elements inside the Window
window_set_window_handlers(s_main_window, (WindowHandlers) {
.load = main_window_load,
.unload = main_window_unload
});
// Show the Window on the watch, with animated=true
window_stack_push(s_main_window, true);
}
Related
I've written a simple DirectX11.2 app, which works. I wanted to add some cleanup code for when the app exits, however I noticed that my window does not actually handle closing, suspending, resuming or uninitializing properly.
According to the IFrameworkView documentation, Uninitialize() should get called before the application exits, but it never gets called (https://learn.microsoft.com/en-us/uwp/api/windows.applicationmodel.core.iframeworkview?view=winrt-19041)
I subscribe to the events that are supposed to fire when a window suspends, resumes, or closes, however it seems like none of those events ever actually fire.
I am under the impression that minimizing the window should suspend the application, clicking on the window from the task bar after it has been minimized should resume the application, and pressing the red X button in the top right corner of the window should close the application, am I wrong?
Here is the relevant code:
// the class definition for the core "framework" of our app
ref class App sealed: public IFrameworkView
{
bool m_windowClosed;
CGame m_game;
public:
// this function subscribes to suspend and resume events, and gets called properly
virtual void Initialize(CoreApplicationView^ appView) {
// set the OnActivated function to handle to Acivated "event"
appView->Activated += ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &App::OnActivated);
CoreApplication::Suspending += ref new EventHandler<SuspendingEventArgs^>(this, &App::Suspending);
CoreApplication::Resuming += ref new EventHandler<Object^>(this, &App::Resuming);
m_windowClosed = false;
}
// this function subscribes to the close() event. This function is called properly, but the Closed event never fires
virtual void SetWindow(CoreWindow^ window){
window->Closed += ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &App::Closed);
}
virtual void Load(String^ entryPoint) {}
virtual void Run() {
m_game.Initialize();
CoreWindow^ Window = CoreWindow::GetForCurrentThread();
// repeat until window closes
while (!m_windowClosed) {
// run processEvents() to dispatch events
// ProcessAllIfPresent makes ProcessEvents return once all events have been processed
Window->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
// run the rest of the game code here
m_game.Update();
m_game.Render();
}
// we never get here!
m_game.Finalize();
}
// never called, even though it should ALWAYS be called when the application exits?
virtual void Uninitialize() {
Log("Uninitialize()");
}
void OnActivated(CoreApplicationView^ coreAppView, IActivatedEventArgs^ args) {
CoreWindow^ window = CoreWindow::GetForCurrentThread();
window->Activate();
}
// never called
void Suspending(Object^ sender, SuspendingEventArgs^ args) {
Log("Suspending()");
}
// never called
void Resuming(Object^ sender, Object^ args) {
Log("Resuming()");
}
// never called
void Closed(CoreWindow^ sender, CoreWindowEventArgs^ args) {
m_windowClosed = true;
Log("Close()");
}
};
// the class definition that creates an instance of our core framework class
ref class AppSource sealed : IFrameworkViewSource {
public:
virtual IFrameworkView^ CreateView() {
// create an App class and return it
return ref new App();
}
};
[MTAThread] // define main() as a multi-threaded-apartment function
// the starting point of all programs
int main(Array<String^>^ args) {
// create and run a new AppSource class
CoreApplication::Run(ref new AppSource());
return 0;
}
Upon further research, I notice that Suspend and Resume are generally called when Windows itself suspends (sleep, hibernate) and resumes ("wakes up" from sleep or hibernate).
I have now found that the only event that's called before my app terminates is the CoreWindow::VisibilityChanged event.
I'm trying to follow the tutorial about Watchfaces creation, but I'm stuck.
I copied the code from the wiki so there shouldn't be any error whatsoever, but I'm getting this error while compiling
error: implicit declaration of function 'PBL_IF_ROUND_ELSE' [-Werror=implicit-function-declaration]
I tried to google it but I couldn't find anything useful.
This is the code
#include <pebble.h>
static Window *s_main_window;
static TextLayer *s_time_layer;
static void update_time() {
// Get a tm structure
time_t temp = time(NULL);
struct tm *tick_time = localtime(&temp);
// Write the current hours and minutes into a buffer
static char s_buffer[8];
strftime(s_buffer, sizeof(s_buffer), clock_is_24h_style() ? "%H:%M" : "%I:%M", tick_time);
// Display this time on the TextLayer
text_layer_set_text(s_time_layer, s_buffer);
}
static void tick_handler(struct tm *tick_time, TimeUnits units_changed) {
update_time();
}
static void main_window_load(Window *window) {
// Get information about the Window
Layer *window_layer = window_get_root_layer(window);
GRect bounds = layer_get_bounds(window_layer);
// Create the TextLayer with specific bounds
s_time_layer = text_layer_create(
GRect(0, PBL_IF_ROUND_ELSE(58, 52), bounds.size.w, 50));
// Improve the layout to be more like a watchface
text_layer_set_background_color(s_time_layer, GColorClear);
text_layer_set_text_color(s_time_layer, GColorBlack);
text_layer_set_text(s_time_layer, "00:00");
text_layer_set_font(s_time_layer, fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD));
text_layer_set_text_alignment(s_time_layer, GTextAlignmentCenter);
// Add it as a child layer to the Window's root layer
layer_add_child(window_layer, text_layer_get_layer(s_time_layer));
}
static void main_window_unload(Window *window) {
// Destroy TextLayer
text_layer_destroy(s_time_layer);
}
static void init() {
// Create main Window element and assign to pointer
s_main_window = window_create();
// Set handlers to manage the elements inside the Window
window_set_window_handlers(s_main_window, (WindowHandlers) {
.load = main_window_load,
.unload = main_window_unload
});
// Show the Window on the watch, with animated=true
window_stack_push(s_main_window, true);
// Make sure the time is displayed from the start
update_time();
// Register with TickTimerService
tick_timer_service_subscribe(MINUTE_UNIT, tick_handler);
}
static void deinit() {
// Destroy Window
window_destroy(s_main_window);
}
int main(void) {
init();
app_event_loop();
deinit();
}
I'm using the CloudPebble SDK.
I got it, PBL_IF_ROUND_ELSE works only with 3.X SDK (I was using the 2.X).
"PBL_IF_ROUND_ELSE(58, 52)" Only works with Pebble Time or SDK3.
You can replace "PBL_IF_ROUND_ELSE(58, 52)" with a range between 0 and 100. 0 meaning it will be at the top of the screen. 100 means it will be at the bottom of the screen.
Replace the "PBL_IF_ROUND_ELSE(58, 52)" with a 0. That should do the trick. Im assuming you are trying to run this program on the aplite version?
So I'm making a zombie shooter game that works well, but after running for a while I get hit with this exception:
Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException:
Couldn't load file: 1zom3.png
at com.badlogic.gdx.graphics.Pixmap.<init>(Pixmap.java:140)
at com.badlogic.gdx.graphics.TextureData$Factory.loadFromFile(TextureData.java:98)
at com.badlogic.gdx.graphics.Texture.<init>(Texture.java:100)
at com.badlogic.gdx.graphics.Texture.<init>(Texture.java:92)
at com.lastride.game.Entity.changeState(Entity.java:51)
at com.lastride.game.Enemy.seek(Enemy.java:39)
at com.lastride.game.LastRideGame.update(LastRideGame.java:149)
at com.lastride.game.LastRideGame.render(LastRideGame.java:229)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:215)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:120)
Caused by: java.io.IOException: Error loading pixmap:
at com.badlogic.gdx.graphics.g2d.Gdx2DPixmap.<init>(Gdx2DPixmap.java:57)
at com.badlogic.gdx.graphics.Pixmap.<init>(Pixmap.java:138)
... 9 more
I know for a fact that the image is there as it works, but it seems that after running for a bit it crashes.
This is the method where it crashes on:
public void changeState(int i)
{
//changes the state and concurrently the image associated with the given state
state = i;
sprite = new Sprite(new Texture(Gdx.files.internal(name+i+suff)));//crashes here
bounding = (sprite.getBoundingRectangle());
if (sprite.getTexture().getTextureData().isPrepared()==false)
{
sprite.getTexture().getTextureData().prepare();
}
playerMap = sprite.getTexture().getTextureData().consumePixmap();
}
As #Tenfour04 points out, it could be an out-of-memory problem.
Instead of doing this:
sprite = new Sprite(new Texture(Gdx.files.internal(name+i+suff)));
Create an global (and/or possible static and/or possible final) Texture object, and load it just once at the beginning of your game and use it repeatably.
Something like this:
public static Texture myTexture_1; //<< your texture
public static final int ID_MY_TEXTURE_1 = 1; //<< this will work as an ID
// This method is called once in your game (like in the create() method)...
public static void load() {
myTexture_1 = new Texture(Gdx.files.internal(name + ID_MY_TEXTURE_1 + suff));
}
// when no longer necessary, remove it...
public static void dispose() {
myTexture_1.dispose();
// and so on...
}
then, in your changeState() method, do a switch to retrieve the correct texture:
public void changeState(int i) {
state = i;
switch(i){
case ID_MY_TEXTURE_1 :
sprite = new Sprite(myTexture_1);
break;
// rest of cases...
}
// rest of your code...
}
The following code is adapted from an example in Real-Time Java Platform Programming by Peter C. Dibble:
import javax.realtime.*;
public class OSTimer {
static volatile boolean cont = true;
public static void main(String[] args) {
AsyncEventHandler handler = new AsyncEventHandler(){
public void handleAsyncEvent() {
System.out.println("Stopping...");
cont = false;
}
}
};
OneShotTimer timer = new OneShotTimer(new RelativeTime(3000, 0), handler);
timer.start();
while(cont){
System.out.println("Running");
if (timer.isRunning()) System.out.println("Timer is running");
try {
Thread.sleep(1000);
} catch(Exception e) { }
}
System.exit(0);
}
The the program is supposed to run for 3 seconds and then exit. However, the output shows that while the timer did indeed stop after 3 seconds, the program continues as usual, i.e. output is:
Running
Timer is running
Running
Timer is running
Running
Timer is running
Running
Running
Running......
Clearly the handler did not fire, and I've no idea why. Another example program involving a periodic timer triggering the handler does work as expected. The program structure is almost the same as the one here.
A few things to try:
Call fire() explicitly on the timer instance to see if you can force things
Try creating your handler by passing in the logic as a Runnable object to the handler. The API is a little unclear on this, but this is how I have specified handlers in the past.
Example:
AsyncEventHandler handler = new AsyncEventHandler(new Runnable() {
public void run() {
System.out.println("Stopping...");
cont = false;
}
});
Processing keeps giving me this error when I run it even though it is just a print command. When I delete the comment block it works fine. Here's the code:
/*
float[] cortToPolar(int xcorr, int ycorr) {
float returns[] = new float[2];
returns[0]= degrees(tan(ycorr/xcorr));
returns[1]= sqrt(pow(xcorr,2)+pow(ycorr,2));
return returns;
}
float lawCos(int a, int b, int c) {
return degrees(
acos(
(pow(a,2)+pow(b,2)-pow(c,2))/
(2*a*b)
)
);
}
*/
print(0);
Why doesn't it like my comment?
Processing runs in two separate modes: static or active
Static mode simply means it's a list of instructions/calls to existing functions (e.g. draw a bunch of lines then exit)
Active mode uses the setup() and draw() calls and runs continuously (gets updated every 'frame').
Only in active mode you are allowed to define own functions like cortToPolar and lawCos (regardless of the fact they are commented - this could be a Processing editor bug).
Use the setup() call to print because using setup will bring Processing into active mode.
/*
float[] cortToPolar(int xcorr, int ycorr) {
float returns[] = new float[2];
returns[0]= degrees(tan(ycorr/xcorr));
returns[1]= sqrt(pow(xcorr,2)+pow(ycorr,2));
return returns;
}
float lawCos(int a, int b, int c) {
return degrees(
acos(
(pow(a,2)+pow(b,2)-pow(c,2))/
(2*a*b)
)
);
}
*/
void setup(){
print(0);
}
(Should you need to use active mode and control how draw() is called you can use noLoop() and loop().)
The message could be shown when the actual problem is a syntax error. I encountered this error with the following (silly) code:
boolean state = false;
setup() {
size(200, 800);
}
void draw() {
}
It is missing the 'void' modifier for the setup function. This is a syntax error (at least, it should be). But the Processing IDE gives you this "active vs. static" message instead.
So in this case, it should be void setup() { } rather than just setup() { }.