I'm making a GTK3 application and I use g_object_set_qdata on a GtkListBoxRow for searching purpose.
I use this code :
GArray *complib;
#define row_get_entry(row) (ElcCompLibEntry*)g_object_get_qdata(G_OBJECT(row),registryquark)
GtkWidget* elc_registry_listbox_make_item(ElcCompLibEntry* curritem)
{
/* I remove UI creation */
GtkWidget* intermediate = gtk_list_box_row_new();
gtk_container_add(GTK_CONTAINER(intermediate),GTK_WIDGET(mainbox));
gtk_widget_show_all(GTK_WIDGET(intermediate));
g_object_set_qdata(G_OBJECT(intermediate),registryquark,curritem);
return intermediate;
};
static GtkWidget* saved = NULL;
GtkWidget* new=elc_registry_listbox_make_item(entry);
gtk_container_add(GTK_CONTAINER(listbox->real_listbox),new);
if (saved)
g_debug("saved entry is at position %d",((gintptr)row_get_entry(saved)-(gintptr)complib->data)/sizeof(ElcCompLibEntry));
saved=new;
g_debug("entry is at position %d",((gintptr)row_get_entry(new)-(gintptr)complib->data)/sizeof(ElcCompLibEntry));
The output of my program :
** (elc:9906): DEBUG: 18:51:10.623: entry is at position 0
** (elc:9906): DEBUG: 18:51:10.625: saved entry is at position -14015
** (elc:9906): DEBUG: 18:51:10.625: entry is at position 1
** (elc:9906): DEBUG: 18:51:10.627: saved entry is at position 32
** (elc:9906): DEBUG: 18:51:10.627: entry is at position 2
** (elc:9906): DEBUG: 18:51:10.629: saved entry is at position 2
** (elc:9906): DEBUG: 18:51:10.629: entry is at position 3
** (elc:9906): DEBUG: 18:51:10.631: saved entry is at position 25921
** (elc:9906): DEBUG: 18:51:10.631: entry is at position 4
ElcCompLibEntry is a simple struct.
g_object_set_qdata_full is just corrupting older datas, the quark is initialized, even when running it in the main thread I got the same result (only the saved entry is at position 2 is constant).
Could someone help find the root of the problem and/or send me to the relevant documentation ?
Thank you for your time !
Per https://developer.gnome.org/glib/stable/glib-Arrays.html#GArray,
The data may be moved as elements are added to the GArray.
It's hard to tell without seeing the code that creates and appends to complib, but complib->data is not constant and your pointers stored in qdata are probably being invalidated when the array is resized.
To prevent this, try creating the array with g_array_sized_new() preallocating the number of elements you need.
Related
I am using tilemaps and animated tiles from the 2dExtras in unity.
My tiles have 6 frames, at speed=2f, and my tilemap frame rate is 2.
New tiles placed always start on frame 1 and then immediately jump to the current frame of the other tiles already placed, the tilemap is keeping every tile at the same pace, which is working as I want.
However I would like the newly placed tiles to start at the frame the others are currently on,(instead of placing a tile that jumps from frame 1 to frame 4) I would like the new tile to start on frame 4
I've found how to pick the frame I want to start on, however I am having trouble retrieving which frame the animation is currently on, so I was wondering how exactly can I access the current frame of animation of a given tilemap ( Or a given tile, I can create a dummy tile and just read the info out of it, how can I get the current frame of an animated tile? )
The animated tilemaps feature seems to lack the feature to retrieve this information, also when I try tilemap.getsprite it always returns the first frame of the sequence(does not return the sprite currently displayed), and there doesn't seem to be any method to poll info from tilemap.animationFrameRate.
I thought another method would be to set a clock and sync it to the rate of the animation but since I can't get the exact framerate duration the clock eventually goes out of sync.
Any help would be appreciated!
I found a way to solve this question. But it's not 100% insurance.
First of all, I used SuperTile2Unity. That doesn't seem to be the point.
private void LateUpdate()
{
// I use this variable to monitor the run time of the game
this.totalTime += Time.deltaTime;
}
private void func()
{
// ...
TileBase[] currentTiles = tilemap.GetTilesBlock(new BoundsInt(new Vector3Int(0, 0, 0), new Vector3Int(x, y, 1)));
Dictionary<string, Sprite> tempTiles = new Dictionary<string, Sprite>();
//I use SuperTiled2Unity. But it doesn't matter, the point is to find animated tile
foreach (SuperTiled2Unity.SuperTile tile in currentTiles)
{
if (tile == null)
{
continue;
}
if (tile.m_AnimationSprites.Length > 1 && !tempTiles.ContainsKey(tile.name))
{
// find animated tile current frame
// You can easily find that the way SuperTile2Unity is used to process animation is to generate a sprite array based on the time of each frame set by Tiled animation and the value of AnimationFrameRate parameter.
// The length of array is always n times of AnimationFrameRate. You can debug to find this.
tempTiles.Add(tile.name, tile.m_AnimationSprites[GetProbablyFrameIndex(tile.m_AnimationSprites.Length)]);
}
}
//...
}
private int GetProbablyFrameIndex(int totalFrame)
{
//According to the total running time and the total length of tile animation and AnimationFrameRate, the approximate frame index can be deduced.
int overFrameTime = (int)(totalTime * animationFrameRate);
return overFrameTime % totalFrame;
}
I have done some tests. At least in 30 minutes, there will be no deviation in animations, but there may be a critical value. If the critical time is exceeded, there may be errors. It depends on the size of AnimationFrameRate and the accumulation mode of totalTime. After all, we don't know when and how the unity deals with animatedTile.
You could try using implementation presented in [1] which looks as follows:
MyAnimator.GetCurrentAnimatorClipInfo(0)[0].clip.length * (MyAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime % 1) * MyAnimator.GetCurrentAnimatorClipInfo(0)[0].clip.frameRate;
[1] https://gamedev.stackexchange.com/questions/165289/how-to-fetch-a-frame-number-from-animation-clip
I want to display some string on 16X02 lcd. For the time being, I am implementing the example given in the following link. My 16X02 lcd's backlight is on and bright, but it is not giving any character as display. What should I do now?
https://www.losant.com/blog/how-to-connect-lcd-esp8266-nodemcu
#include <LiquidCrystal_I2C.h>
// Construct an LCD object and pass it the
// I2C address, width (in characters) and
// height (in characters). Depending on the
// Actual device, the IC2 address may change.
LiquidCrystal_I2C lcd(0x27, 16, 2); // my lcd pin address is different from the example
void setup() {
// The begin call takes the width and height. This
// Should match the number provided to the constructor.
Serial.begin(115200);
Serial.println ("In Setup");
lcd.begin(16,2);
lcd.init();
// Turn on the backlight.
lcd.backlight();
// Move the cursor characters to the right and
// zero characters down (line 1).
lcd.setCursor(5, 0);
// Print HELLO to the screen, starting at 5,0.
lcd.print("HELLO");
// Move the cursor to the next line and print
// WORLD.
lcd.setCursor(5, 1);
lcd.print("WORLD");
}
void loop() {
}
I'm assuming you are verified your physical connection and providing proper voltage supply.
Are you using the same I2C to GPIO expansion module PCF8574. If no the you may need to modify the LCD module.
Also verify if you have set the proper contrast voltage by adjusting the pot. You should first set it to value where by you can see all background dots (pixels); once text is visible you can set it to optimum value.
I am using Jquery file upload basic. To show progress bar I am using 'fileuploadprogressall' event binding
$('#fileupload').fileupload().bind('fileuploadprogressall', function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
console.log(data.loaded +" "+data.total+" "+progress);
$('#progress').css('visibility','visible');
$('#progress .bar').css(
'width',
progress + '%'
);
It works fine in FF and Chrome and shows the progress. But in IE11 to 9, it is called only two times, one with 0% and another one with 100%.
So the progress bar hides even before the file is actually loaded.
Below is the output of a file with size
DATA loaded total data percentage
271 128584 0
128584 128584 100
Can someone please help to figure out why it is being called only twice?
There are 3 properties that I want to set for some VBA form comboboxes and I don't know if it's possible.
I don't want to let the combobox editable. Right now if the user types something in it that it submits the form it will send that value... I want to let him choose only from the values I added in the Combobox.
I want to make the list of items in the combobox scroll-able. Right now I'm able to scroll through the list if I use the scroll-bar but I don't know why I can't scroll with the mouse scroll.
And I want to jump to some item if I start typing. Let's say I have the months of the year in one combobox... if I start to type mar I want it to jump to march. I know that for the html forms this properties is by default but I don't know about VBA forms...
Thanks a lot
Of the behaviours you want, some are possible with settings on the Combo, others you will need to code
List of Months: Put a list of entries on a (hidden) sheet and name the range. Set .RowSource to that range
Match as you type: Set properties .MatchEntry = fmMatchEntryComplete and .MatchRequired = True
Reject non list entries: A Combo with these settings will allow you to type an invalid entry, but will reject it with an error message popup when you commit. If you want to silently reject invalid data as you type, you will need to code it.
If you want the selected value returned to a sheet, set .ControlSource to a cell address (preferable a named range)
By "...scroll with the mouse scroll..." I assume you mean the mouse wheel. Unfortunatley Forms don't support mouse wheel scroll. You will have to code it yourself. There is a Microsoft patch for this at here (not tried it myself yet)
Sample code to silently reject invalid entries
Private Sub cmbMonth_Change()
Static idx As Long
Dim Match As Boolean
Dim i As Long
If cmbMonth.Value = "" Then Exit Sub
If idx = 0 Then idx = 1
i = idx
Match = False
For i = 0 To cmbMonth.ListCount
If cmbMonth.List((i + idx - 1) Mod cmbMonth.ListCount) Like cmbMonth.Value & "*" Then
cmbMonth.ListIndex = (i + idx - 1) Mod cmbMonth.ListCount
Match = True
Exit For
End If
Next
If Not Match Then
cmbMonth.Value = Left(cmbMonth.Value, Len(cmbMonth.Value) - 1)
End If
End Sub
Set the propertie MatchEntry of combobox to 1 (fmMatchEntryComplete) and MatchRequired to true for example
combobox1.MatchEntry=1
combobox1.MatchRequired=True
[]'s
This works:
(Get-Host).UI.RawUI
$a = (Get-Host).UI.RawUI
$a.BackgroundColor = "white"
$a.ForegroundColor = "black"
$size = (Get-Host).UI.RawUI.WindowSize
$size.Width = 80
$size.Height = 30
(Get-Host).UI.RawUI.WindowSize = $size
But this doesn't work, and I am not sure how to make it work:
$position = (Get-Host).UI.RawUI.Windowposition
$position.X = 0
$position.Y = 30
(Get-Host).UI.RawUI.Windowposition = $position
The error I get is strange. It complains about "buffer" when I am trying to set external window position:
Exception setting "WindowPosition": "Cannot use the
specified Window X (column) position because it extends
past the width of the screen buffer. Specify another X
position, starting with 0 as the left most column of
the buffer.
The error is not really strange, because WindowPosition Gets and sets the position, in characters, of the view window relative to the screen buffer.
It does not set the position of the Window, but to put it crudely, the position in the buffer that you see through the view of the window. So in your case, you are getting the error because it is outside the buffer.
http://msdn.microsoft.com/en-us/library/system.management.automation.host.pshostrawuserinterface.windowposition%28v=vs.85%29.aspx
Unfortunately, setting the position of the window is not simple. There is a snapin for it though - http://wasp.codeplex.com/ ( use Set-WindowPosition)
Take a look at this script: Resize-Console.ps1 – Resize console window/buffer using arrow keys.
It is hopefully useful itself and partially should answer the question (the size part).