Using classes inside FreePie scripts

Official forum for open source FreePIE discussion and development.
Post Reply
NoxWings
One Eyed Hopeful
Posts: 44
Joined: Thu May 15, 2014 8:04 am

Using classes inside FreePie scripts

Post by NoxWings »

Hi!

First of all this is the first time ever I'm making my own FreePie script or using python.

I'm doing a script to translate speech commands into key commands: press 1 or N keys at the same time, holding them or executing a sequence.

My first question was about time event handling. if there was something already implemented inside freePIE to hold a button a certain time or call a function every certain amount of time easier, but looks like I'll be using standard python "time":
http://www.mtbs3d.com/phpBB/viewtopic.php?f=139&t=19651

But now I am wondering about declaring/parsing classes in FreePIE script. What's is the correct/optimal way to go?

Code: Select all

class KeyPress:
	def __init__(self, key):
		blablabla

if starting:
	...blablabla...
Is the class going to be parsed in each FreePIE update and consecuently be a performance issue?
should I use the following instead?

Code: Select all

if starting:
	class KeyPress:
		def __init__(self, key):
			blablabla

	...blablabla...
NoxWings
One Eyed Hopeful
Posts: 44
Joined: Thu May 15, 2014 8:04 am

Re: Using classes inside FreePie scripts

Post by NoxWings »

Nevermind, I still don't know wich one is better but looks like there will be no noticeable performance issues. Sorry about the silly question.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: Using classes inside FreePie scripts

Post by CyberVillain »

The python engine will only define the class once, so nothing to gain from doing it from the if starting closure.


About the time feature i'm planning on fixing that, but time is scarce

edit: Btw, beware of using filter methods from a declared function or class. Most of the filter functions and also diagnostics.watch uses the argument as a key

for example

Code: Select all

delta = filters.delta(android[0].yaw)
Will use "android[0].yaw" as a key to store the value between executions. If you use the method from a declared function like

Code: Select all

def calculateDelta(x):
   return filters.delta(x)
Now filters.delta will use "x" as the key, so if you do

Code: Select all

x = calculateDelta(android[0].yaw)
y = calculateDelta(android[0].pitch)
It will use the same key to store the values and the delta value will be all wrong

This could be considered a bug, buts its very hard to fix. I havent gotten around to figure out a way.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: Using classes inside FreePie scripts

Post by CyberVillain »

added a stopWatch method that will be added in next version¨

Code: Select all

if filters.stopWatch(keyboard.getKeyDown(Key.A), 5000):
	diagnostics.debug("Key down for 5 sec")
How does Glovepie work, does it require you to release the button until it starts the timer again? My code curretly does not requiore this so if you hold Key.A down it will print the message each 5 seconds.
NoxWings
One Eyed Hopeful
Posts: 44
Joined: Thu May 15, 2014 8:04 am

Re: Using classes inside FreePie scripts

Post by NoxWings »

CyberVillain wrote:added a stopWatch method that will be added in next version¨

Code: Select all

if filters.stopWatch(keyboard.getKeyDown(Key.A), 5000):
	diagnostics.debug("Key down for 5 sec")
How does Glovepie work, does it require you to release the button until it starts the timer again? My code curretly does not requiore this so if you hold Key.A down it will print the message each 5 seconds.
Sorry, I've never used GlovePIE before but I'm indeed having problems replicating a key hold.

I've tried 2 aproaches that didn't work
1.- Using "keyboard.setKey( k, True )" once and "keyboard.setKey( k, False )" once after N seconds.
2.- Using "keyboard.setKey( k, True )" on every FreePIE pass while the button is supposed to be held down and then "keyboard.setKey( k, False )" once after N seconds.

None of them are working :S though I haven't tested it in any game, only looking at the keys written on a notepad.

Currently the code I'm using to hold a button looks like this:

There are 3 classes there:
- KeyAction is an abstract class to store a list of keys and define "execute" and "update" functions
- execute: is a function that will be called when a certain command is said
- update: will be called on every pass and will update the action if needed (f.i. releasing the a key)
-KeyHold is a class derived from KeyAction
-VoiceCommand is the class that stores and handles the speech commands and responses

Code: Select all

import time;

# ***********************************
# Key Actions & VoiceCommand Classes
# ***********************************

class KeyAction:
	def __init__(self, key):
		self.keys = []
		# append or extend (both are valid)
		if isinstance(key, list):
			self.keys.extend(key)
		else:
			self.keys.append(key)
	
	def setKeyDown(self):
		for key in self.keys:
			keyboard.setKeyDown(key)	
		
	def setKeyUp(self):
		for key in self.keys:
			keyboard.setKeyUp(key)	
	
	def setKey(self, down):
		for key in self.keys:
			keyboard.setKey(key, down)
			
	def setKeyPressed(self):
		for key in self.keys:
			keyboard.setPressed(key)	
	
	def execute(self):
		raise NotImplementedError("Subclass must implement execute method")

	def update(self, curentTime):
		pass


class KeyHold(KeyAction):
	def __init__(self, key, duration):
		KeyAction.__init__(self, key)
		self.duration = duration
		self.time = time.time()
		self.needUpdate = False
		
	def execute(self):
		# set the keys down
		self.setKey(True)
		# start the update timer
		self.time = time.time()
		self.needUpdate = True
			
	def update(self, currentTime):
		if self.needUpdate:
			# determine if we should stop pressing the keys
			if (currentTime - self.time) >= self.duration:
				self.needUpdate = False
				diagnostics.debug("Releasing")
				self.setKeyUp(False)
			else:
				diagnostics.debug("Holding")	
				self.setKey(True)
				
				
class VoiceCommand:
	def __init__(self, cmd, response, action = None):
		self.cmd = cmd
		self.response = response
		self.action = action
		
	def said(self, confidence, response=False):
		return ((self.cmd != "") and speech.said(self.cmd, confidence))

	def playResponse(self):
		if self.response:
			speech.say(self.response)
		
	def execute(self):
		if self.action:
			self.action.execute()
			
	def update(self, currentTime):
		if self.action:
			self.action.update(currentTime)


# ***********************************
# Config and commands
# ***********************************

if starting:
	confidenceLevel = 0.7

	commands =	[
	VoiceCommand("Testing",
				"Holding Button",
				KeyHold( Key.A, 2 ))
	]


# ***********************************
# Main Loop
# ***********************************

currentTime = time.time()
for command in commands:
	# if said execute action
	if command.said(confidenceLevel):
		command.playResponse()
		command.execute()
	command.update(currentTime)

Last edited by NoxWings on Tue Jul 22, 2014 12:31 pm, edited 1 time in total.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: Using classes inside FreePie scripts

Post by CyberVillain »

Ah, you want to emulate a keyhold for a interval of time, sorry. I thought you wanted to check if a key was hold for a interval of time.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: Using classes inside FreePie scripts

Post by CyberVillain »

It does not work in Notepad, but it works in DirectX/RawInput software. So should work in game.
NoxWings
One Eyed Hopeful
Posts: 44
Joined: Thu May 15, 2014 8:04 am

Re: Using classes inside FreePie scripts

Post by NoxWings »

CyberVillain wrote:It does not work in Notepad, but it works in DirectX/RawInput software. So should work in game.
Actually, it is working perfect in-game ^^. Thank you.
NeoTokyo_Nori
Cross Eyed!
Posts: 144
Joined: Wed Jul 16, 2014 10:29 am
Location: Tokyo, Japan

Re: Using classes inside FreePie scripts

Post by NeoTokyo_Nori »

Hi CV,

I think I need to have the key or mouse, stay down for at least 50ms or so,
because my game is not responding to the gun inputs consistently.
Even though the inputs are showing up properly in the debug values.

So I tried using your stopWatch example

Code: Select all

if filters.stopWatch(keyboard.getKeyDown(Key.A), 5000):
   diagnostics.debug("Key down for 5 sec")
but I keep getting "wrong number of arguments" errors...

whats going on? :?
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: Using classes inside FreePie scripts

Post by CyberVillain »

Strange that works for me (Just so that everybody know, this feature is yet not in the installer release).

IS that your entire script?
NeoTokyo_Nori
Cross Eyed!
Posts: 144
Joined: Wed Jul 16, 2014 10:29 am
Location: Tokyo, Japan

Re: Using classes inside FreePie scripts

Post by NeoTokyo_Nori »

Hi CV,

I have attached the code I am using to test the button IO,
The gun IMU code is striped out, because I was getting
input lag of 5 seconds plus (!) when handling the IMU and button IO together.
So I am testing the button IO code alone, to figure out where the lag is coming from... :ugeek:

I am still getting the same error for the stopWatch code part...:?
Any ideas ?
Last edited by NeoTokyo_Nori on Sat Sep 13, 2014 11:46 am, edited 2 times in total.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: Using classes inside FreePie scripts

Post by CyberVillain »

Really strange, I built againts the Generic com branch and it works for me
NeoTokyo_Nori
Cross Eyed!
Posts: 144
Joined: Wed Jul 16, 2014 10:29 am
Location: Tokyo, Japan

Re: Using classes inside FreePie scripts

Post by NeoTokyo_Nori »

Yes it is strange..

I just tested a script which has basically nothing other than the stopWatch code
and a keyboard update check, and it is running without error.

So there must be something wrong with my other part of the code,
even though that part runs without error too...
:roll:
Post Reply

Return to “FreePIE”