Not able to use setFillColor method on display objects within a table - lua

So I have a collection of display objects in a table, inserted like so (some excess code was taken out):
for i=1,blockCount do
local block=display.newRect(xcoord,ycoord,blockwidth,blockheight);
local color=blocks[i];
if(color=="red") then
block:setFillColor(1,0,0);
block.collision = redHit;
block:addEventListener( "collision",block);
elseif(color=="blue") then
block:setFillColor(0,0,1);
block.collision = blueHit;
block:addEventListener( "collision",block);
block.hp=0;
elseif(color=="yellow") then
block:setFillColor(1,1,0);
block.collision = yellowHit;
block:addEventListener( "collision",block);
else
end
block.blockColor=color;
grid[i]=block;
end
So grid is just a table full of rectangle objects with different properties. However, in a different spot in the code, I am trying to do this:
for i=1,blockCount do
if (grid[i]~=nil) then
local color=grid[i].blockColor;
if (color=="blue") then
grid[i]:setFillColor(1,0,0);
grid[i].collision = redHit;
grid[i].blockColor="red";
elseif (color=="red") then
grid[i]:setFillColor(0,0,1);
grid[i].collision = blueHit;
grid[i].blockColor="blue";
grid[i].hp=0;
end
end
end
In other words, at this spot in the code, I am trying to make all red blocks blue and all blue blocks red. But it's throwing an error that it's unable to change the fill color (saying it's a nil value). Because it is getting there, it is pulling the information from the object by seeing its color, so it is not unable to access properties and functions of the object, and if I comment out that line, changing the other properties works. Why would it not be able to run this simple function?

It means that yours grid table contains not only block elements. So one of elements stored in grid table contains no ".blockColor".
Change it to:
if (grid[i]~=nil and grid[i].blockColor) then

Related

Can't figure out what to hook into in order to add text into GameTooltip when hovering over applicants in LFG

I'm making an addon that adds some information to the LFG both when applying to them and when picking applicants for your own group. There are different functions and different templates for the frames for searching LFG and hosting LFG. For searching, you can use hooksecurefunc on LFGListUtil_SetSearchEntryTooltip and that will allow you to get the information on whatever group the player is hovering over.
hooksecurefunc("LFGListUtil_SetSearchEntryTooltip", function(gametooltip, resultID, autoAcceptOption)
--debugPrint("LFGListUtil_SetSearchEntryTooltip")
local entry = C_LFGList.GetSearchResultInfo(resultID)
if not entry or not entry.leaderName then
return
end
local skill, attitude, note, playerNumber = self:getPlayer(self:addServerName(entry.leaderName))
--debugPrint("hooked correctly!")
GameTooltip:AddLine("\n")
if skill ~= 0 then
GameTooltip:AddDoubleLine("Skill:", tostring(skill), 1,0.82,0.0,1,1,1)
end
if attitude ~= 0 then
GameTooltip:AddDoubleLine("Attitude:", tostring(attitude), 1,0.82,0.0,1,1,1)
end
if note ~= "" then
GameTooltip:AddLine(note,1,1,1,true)
end
end)
This method seems to almost work when you're looking for applicants to your own group. According to Wow's UI source xml, the function "LFGListApplicantMember_OnEnter" triggers whenever you enter a frame made with the LFGListApplicantMemberTemplate. As far as I can tell from the LFGList's .lua file, all of the members of an applying group should have this template. However, it only triggers when hovering over the not-leading member of a group or when hovering over their role icons.
Is there some other function I'd be able to hook into in order to make it work on the leading group? I know it's possible to add text to the tooltip of a leading member because the RaiderIO addon does it, but I can't figure out how they do it. It needs to have some way of getting the name of the player you're hovering over to use my getPlayer function on it.
This is my current test function, though obviously it doesn't work
hooksecurefunc("LFGListApplicantMember_OnEnter", function(...)
GameTooltip:AddLine("")
GameTooltip:AddLine("TestText")
debugPrint("Hooked Successfully")
end)
and this is debugPrint
local function debugPrint(...)
print(...)
end

Lua - table won't insert from function

I have a Lua function where I build a table of value and attempt to add it to a global table with a named key.
The key name is pulled from the function arguments. Basically, it's a filename, and I'm pairing it up with data about the file.
Unfortunately, the global table always comes back nil. Here's my code: (let me know if you need to see more)
(Commented parts are other attempts, although many attempts have been deleted already)
Animator = Class{}
function Animator:init(atlasfile, stringatlasfriendlyname, totalanimationstates, numberofframesperstate, booleanstatictilesize)
-- Define the Animator's operation mode. Either static tile size or variable.
if booleanstatictilesize ~= false then
self.isTileSizeStatic = true
else
self.isTileSizeStatic = false
end
-- Define the total animation states (walking left, walking right, up down, etc.)
-- And then the total frames per state.
self.numAnimationStates = totalanimationstates or 1
self.numAnimationFrames = numberofframesperstate or 2
-- Assign the actual atlas file and give it a programmer-friendly name.
self.atlasname = stringatlasfriendlyname or removeFileExtension(atlasfile, 'animation')
generateAnimationQuads(atlasfile, self.atlasname, self.numAnimationStates, self.numAnimationFrames)
end
function generateAnimationQuads(atlasfile, atlasfriendlyname, states, frames)
spriteWidthDivider = atlasfile:getWidth() / frames
spriteHeightDivider = atlasfile:getHeight() / states
animationQuadArray = generateQuads(atlasfile, spriteWidthDivider, spriteHeightDivider)
animationSetValues = {atlasarray = animationQuadArray, width = spriteWidthDivider, height = spriteHeightDivider}
--gAnimationSets[#gAnimationSets+1] = atlasfriendlyname
gAnimationSets[atlasfriendlyname] = animationSetValues
--table.insert(gAnimationSets, atlasfriendlyname)
end
Note: when using print(atlasfriendlyname) and print(animationSetValues), neither are empty or nil. They both contain values.
For some reason, the line(s) that assign the key pair to gAnimationSets does not work.
gAnimationSets is defined a single time at the top of the program in main.lua, using
gAnimationSets = {}
Animator class is called during the init() function of a character class called Bug. And the Bug class is initialized in the init() function of StartState, which extends from BaseState, which simply defines dummy init(), enter(), update() etc. functions.
StartState is invoked in main.lua using the StateMachine class, where it is passed into StateMachine as a value of a global table declared in main.lua.
gAnimationSets is declared after the table of states and before invoking the state.
This is using the Love2D engine.
Sorry that I came here for help, I've been picking away at this for hours.
Edit: more testing.
Trying to print the animationQuadArray at the index gTextures['buganimation'] always returns nil. Huh?
Here's gTextures in Main.lua
gTextures = {
['background'] = love.graphics.newImage('graphics/background.png'),
['main'] = love.graphics.newImage('graphics/breakout.png'),
['arrows'] = love.graphics.newImage('graphics/arrows.png'),
['hearts'] = love.graphics.newImage('graphics/hearts.png'),
['particle'] = love.graphics.newImage('graphics/particle.png'),
['buganimation'] = love.graphics.newImage('graphics/buganimation.png')
}
Attempting to return gTextures['buganimation'] returns a file value as normal. It's not empty.
My brain is so fried right now I can't even remember why I came to edit this. I can't remember.
Global table in Main.lua, all other functions can't access it.
print(gTextures['buganimation']) works inside the function in question. So gTextures is absolutely accessible.
Table isn't empty. AnimationSetValues is not empty.
I'm adding second answer because both are correct in context.
I ended up switching IDE's to VS Code and now the original one works.
I was originally using Eclipse LDT with a Love2D interpreter and in that environment, my original answer is correct, but in VS Code, the original is also correct.
So Dimitry was right, they are equivalent, but something about my actual Eclipse setup was not allowing that syntax to work.
I switched to VS Code after I had another strange syntax problem with the interpreter where goto syntax was not recognized and gave a persistent error. The interpreter thought goto was the name of a variable.
So I switched, and now both things are fixed. I guess I just won't use LDT for now.
Solution: Lua syntax. Brain Fry Syndrome
I wrote:
animationSetValues = {atlasarray = animationQuadArray, width = spriteWidthDivider, height = spriteHeightDivider}
Should be:
animationSetValues = {['atlasfile']=atlasfile, ['atlasarray']=animationQuadArray, ['width']=spriteWidthDivider, ['height']=spriteHeightDivider}
Edit: I'm fully aware of how to use answers. This was posted here to reserve my spot for an answer so I could edit it later when I returned back home, which is exactly what I'm doing right now. I'll keep the old post for archival purposes.
Original:
I solved it. I apologize for not posting the solution right now. My brain is melted into gravy.
I will post it tomorrow. Just wanted to "answer" saying no need to help. Solved it.
Solution is basically, "oh it's just one of those Lua things". Wonderful. I'm having so much fun with this language - you can tell by my blank expression.
From the language without line endings or brackets, but forced print parentheses... ugh. I'm going back to C# when this class is done.

Saving a composite datawindow in PowerBuilder

Is there a way to save results in a composite datawindow as a text or excel spreadsheet? Powerbuilder states for composites the format to save it is PSReport. That doesn't work for what I'm trying to do. Is there any other workaround for this issue?
A composite datawindow may contain any number of nested datawindows. So if memory serves, you cannot save the entire composite datawindow as data in a meaningful way (SaveAs will just give you a one-line bit of meaningless data), but you CAN save each of the nested datawindows inside the composite.
Here is some PFC code I wrote (for inside a menu item) which makes a copy of a nested report and then executes a SaveAs (dialog in this case):
//must create a 'dummy' datawindow,
//and put the data on the nested report into it
u_dw ldw_Temp
Window lw_Parent
String ls_Syntax, ls_Error
If Not IsValid(i_dwo) Then
MessageBox('Unexpected Error', &
'The pointer to the datawindow object was invalid. Contact Systems.')
Return
End If
If i_dwo.Type = 'report' Then
//continue
Else
MessageBox('Unexpected Error', &
'The pointer did not refer to a report. Contact Systems.')
Return
End If
If idw_Parent.of_GetParentWindow(lw_Parent) = 1 Then
ls_Syntax = i_dwo.object.datawindow.syntax
If lw_Parent.OpenUserObject(ldw_Temp) = 1 Then
If ldw_Temp.Create(ls_Syntax,ls_Error) = 1 Then
ldw_Temp.Object.Data.Primary = i_dwo.Object.Data.Primary
ldw_Temp.Event pfc_SaveAs()
Else
If IsNull(ls_Error) Or ls_Error = '' Then ls_Error = '<unknown error>'
MessageBox('Error','Error creating datawindow object: ' + ls_Error)
End If
lw_Parent.CloseUserObject(ldw_Temp)
Else
MessageBox('Error','Error creating datawindow control on ' + lw_Parent.ClassName())
End If
Else
MessageBox('Error','Unable to obtain pointer to the parent window.')
End If
Basically this code gets the syntax of the datawindow object underlying the nested report (ls_Syntax = i_dwo.object.datawindow.syntax above), then creates a datawindow control on the parent form and loads that syntax into it, and then copies the data from the one into the other. Finally it calls SaveAs on the copy, and the user is presented with a dialog asking where they want to save the data from the nested report and in what format.
You could automate this so that it saves each nested report as a separate file, and then if you like you could automate the formation of those separate files into a single file (sheets inside a workbook, appended text files, etc).
There are other ways to do what you are asking, depending on what exactly you are trying to accomplish.
The i_dwo variable was loaded in the right-mouse up even of the datawindow control (the dwo event variable there).
That may get you running, please ask questions if you have any.

Conditionally set OLE definition

In Clarion, I'm looking to set the definition for an OLE dynamically in a window. Right now, this is how I define two OLE objects in a window:
Window WINDOW('Test ActiveX Window'), AT(,,431,92), FONT('MS Sans Serif', 8,, FONT:regular), COLOR(COLOR:White), CENTER, ALRT(F2Key), TIMER(10), GRAY
OLE, AT(10,3,11,7), USE(?MyOLE1), HIDE, CREATE('MyActiveX.MyActiveXCtrl.1'), COMPATIBILITY(021H) END
OLE, AT(30,3,11,7), USE(?MyOLE2), HIDE, CREATE('SomeOtherActiveX.SomeOtherActiveXCtrl.1'), COMPATIBILITY(021H) END
END
Both objects contain the same method definitions (ex. TestMethod), almost like they implement a common interface. I can currently call them conditionally like this:
if (condition)
testStr = ?MyOLE1{'TestMethod(param1)'}
else
testStr = ?MyOLE2{'TestMethod(param1)'}
end
What I'd like to do is only create one object, and then dynamically set the control's definition. I know there are other ways to simplify this (OCX wrappers, etc), but based on the project's requirements, this is how it has to be done. At some point, this code will grow from 2 objects to many more and this will be a lot cleaner.
How can I dynamically set the control's definition (the MyActiveX.MyActiveXCtrl.1 part)?
Here is how to create an OLE object dynamically:
Data
MyOLE Long
Code
MyOLE = 0
MyOLE = Create(0, CREATE:OLE)
! Set the OLE's control definition dynamically:
if (condition)
?MyOLE{PROP:Create} = 'ACTIVEXIDTECH.ActiveXIDTechCtrl.1'
else
?MyOLE{PROP:Create} = 'SomeOtherActiveX.SomeOtherActiveXCtrl.1'
end

Nokogiri/Ruby array question

I have a quick question. I am currently writing a Nokogiri/Ruby script and have the following code:
fullId = doc.xpath("/success/data/annotatorResultBean/annotations/annotationBean/concept/fullId")
fullId.each do |e|
e = e.to_s()
g.write(e + "\n")
end
This spits out the following text:
<fullId>D001792</fullId>
<fullId>D001792</fullId>
<fullId>D001792</fullId>
<fullId>D008715</fullId>
I wanted the just the numbers text in between the "< fullid>" saved, without the < fullId>,< /fullId> markup. What am I missing?
Bobby
I think you want to use the text() accessor (which returns the child text values), rather than to_s() (which serializes the entire node, as you see here).
I'm not sure what the g object you're calling write on is, but the following code should give you an array containing all of the text in the fullId nodes:
doc.xpath(your_xpath).map {|e| e.text}

Resources