I created a app by script editor ,using applescript . In the code , i used "repeat ... end repeat" to mock a timer . When the code was compiled, i ran the app . it worked fine , but ,if i right click the app icon ,and chose menu "Quit" , nothing happen.
I know i should do a "EXIT" checking , but , i don't know how to do that.
Anybody can help?
on main()
set f1 to "/System/Library/Sounds/Pop.aiff"
set f2 to "/System/Library/Sounds/Ping.aiff"
set f3 to "/System/Library/Sounds/Glass.aiff"
set f4 to "/System/Library/Sounds/Tink.aiff"
repeat
set now to current date
set h to hours of now
set m to minutes of now
set s to seconds of now
if (h = 6) and (m = 30) and (s = 0) then
--some code here
end if
delay 0.5
end repeat
end main
The repeat loop blocks the code.
As the code is saved as application use the on idle handler which is called periodically depending on the return value.
global f1, f2, f3, f4
on run
set f1 to "/System/Library/Sounds/Pop.aiff"
set f2 to "/System/Library/Sounds/Ping.aiff"
set f3 to "/System/Library/Sounds/Glass.aiff"
set f4 to "/System/Library/Sounds/Tink.aiff"
end run
on idle
set {hours:h, minutes:m, seconds:s} to current date
if (h = 6) and (m = 30) and (s = 0) then
--some code here
end if
return 1
end idle
Related
How can I start the script with a normal key, not a G-key?
Like SHIFT+K or just K.
local function interruptable_sleep(delay)
local tm = GetRunningTime() + delay
repeat
if IsKeyLockOn("scrolllock") then return true end
local t = tm - GetRunningTime()
if t > 0 then Sleep(math.min(t, 100)) end
until t <= 0
end
function OnEvent(event, arg)
if event=="G_PRESSED" and arg==3 then --This change for "K" or something not a G-Key
I am making a Roblox game and I want it to have a stopwatch. The stopwatch works, but it counts very slowly for some reason.
Here's my ScreenGui in StarterGui:
Here's the code inside the LocalScript:
local timer = script.Parent.Timer
local tms = 00
local ts = 00
local tm = 00
local tt
local tts
local y = 0
local whichtower = game.Players.LocalPlayer:FindFirstChild("WhichTower")
while true do
wait(0.01)
if whichtower.Value == "" then
tms = 00
ts = 00
tm = 00
tts = 0
else
tms = tms + 1
if tms == 100 then
ts = ts + 1
tms = 0
tts = tts + 1
if ts == 60 then
tm = tm + 1
ts = 0
end
end
tt = tostring(tm)..":"..tostring(ts)..":"..tostring(tms)
timer.Text = tt
game.Players.LocalPlayer:FindFirstChild("Time").Value = tt
end
end
The arbitrary wait() and loop is a possible cause of timing issues, although I can't see anything specific that might be slowing it down. Are you sure that :FindFirstChild on WHichTower is always returning results? Add a print statement there, so your debug window has a constant stream of values, and you can confirm if it's finding a suitable tower.
Also, you are only updating the text if there's a Tower; for the code where you set the values to 0, there's no timer.Text update.
But if you don't think that's the issue:
I'd try put your code in a Heartbeat function, called regularly and tied to the refresh rate (I think). Then you don't need the while loop, nor the wait() commands. The Heartbeat only runs as fast as the refresh rate, therefore, there's no point trying to running anything quicker than that because the screen won't update.
local lPlayers = game:GetService("Players")
local lRunSvc = game:GetService("RunService")
local function onPlayerAdded(pPlayer) -- pPlayer (variable name is up to you) is the ref to the joined player.
print(pPlayer.Name .. " joined the game.")
lRunSvc.Heartbeat:Connect(function()
print("whichtower.value is:" .. whichtower.Value) -- View prints in the Output console
if whichtower.Value == "" then
tms = 00
ts = 00
tm = 00
tts = 0
else
tms = tms + 1
if tms == 100 then
ts = ts + 1
tms = 0
tts = tts + 1
if ts == 60 then
tm = tm + 1
ts = 0
end
end
tt = tostring(tm)..":"..tostring(ts)..":"..tostring(tms)
timer.Text = tt
game.Players.LocalPlayer:FindFirstChild("Time").Value = tt
end
end)
end
lPlayers.PlayerAdded:Connect(onPlayerAdded) -- This is called when a player joins
Just as Vexen Crabtree has pointed out, the time that wait() will actually pause a script is based on a system clock's best guess of how much time has passed. Rather than counting up the milliseconds, a more reliable method for calculating passed time is to use the tick() function.
tick() will give you the current epoch time, which is the number of milliseconds that have passed since January 1st, 1970.
So, if you know a starting time, you can subtract it from the current time and get the number of milliseconds that have passed. This method doesn't rely on loop timings and will give a more accurate measure of the actual time that has passed. The amount of time that you chose with wait() will only reflect the speed at which the value will be updated.
local timer = script.Parent.Timer
local whichtower = game.Players.LocalPlayer:FindFirstChild("WhichTower")
local playerTime = game.Players.LocalPlayer:FindFirstChild("Time")
local startingTime = 0
local isTiming = false
-- attach a listener to know when to start the clock
whichTower.Changed:Connect(function(newValue)
-- reset the clock to zero when the value is empty
isTiming = newValue ~= ""
if not isTiming then
startingTime = 0
else
-- start the clock!
startingTime = tick()
end
end)
local refreshTime = 0.01
while true do
wait(refreshTime)
if isTiming then
-- calculate the time that has passed
local ms = tick() - startingTime
-- calculate how many minutes have passed
local tm = ms - (ms % (60 * 1000))
ms = ms - tm
tm = tm / 1000
-- calculate how many seconds have passed
local ts = ms - (ms % 1000)
ms = ms - ts
ts = ts / 1000
-- format the remainder
local tms = ms / 1000
if #tostring(tms) > 2 then
tms = string.sub(tostring(tms), 3)
else
tms = "0"
end
-- format the time into mm:ss.ss ex) 123:01.123
local tt = string.format("%.2d:%.2d.%s", tm, ts, tms)
timer.Text = tt
playerTime.Value = tt
end
end
I have figured it out using a different set of code. Roblox limits the wait parameters to a minimum of 0.03 seconds, so that is why my previous code was not working.
This bit of AppleScript works. If I have the System Preferences Sound panel open, and run it in the Script Editor app, it changes the volume to be at 50%.
tell application "System Events"
tell process "System Preferences"
set v to value of slider 0 of window 0
log v
set value of slider 0 of window 0 to 0.5
end tell
end tell
This, which tries to be the same thing, fails. Anyone know how to fix it?
var se = Application("System Events");
var spp = se.processes["System Preferences"];
spp.windows[0].sliders[0].value = 0.5
var curr = spp.windows[0].sliders[0].value();
console.log("Current value: " + curr + " - " + typeof(curr));
It ends up setting it to 0. It seems I can only set the volume to 0 or 1. In reality I'm trying to script another application, but this boils down the problem.
As I noted in my comment, I'm 90% sure this is a bug.
Here's a workaround:
app = Application.currentApplication();
app.includeStandardAdditions = true;
try {
app.doShellScript('osascript -e \'tell application "System Events" to set value of slider 0 of window 0 of process "System Preferences" to 0.2\'');
} catch (error ) {
-1;
}
My clipboard controller could have several items copied to the clipboard when using a hotkey (CTRL + SHIFT + Q), instead of only one item, and pastes all at once (CTRL + SHIFT + W), or paste any of the first 10 items directly (CTRL + SHIFT + 1 … 9). Another option is to clear the clipboard (CTRL + SHIFT + -).
It works just for several copy and pastes, but then trying to make a copy operation nothing is added to the buffer. I couldn't find a reason for this.
Code (problem should be in the addToClipboard() or getAll()) :
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <array.au3>
Global $clipBoard[50]=[""]
Global $counter = 0
HotKeySet("^+q","addToClipboard")
HotKeySet("^+-","emptyAll")
HotKeySet("^+w","getAll")
HotKeySet("^+1","get1")
HotKeySet("^+2","get2")
HotKeySet("^+3","get3")
HotKeySet("^+4","get4")
HotKeySet("^+5","get5")
HotKeySet("^+6","get6")
HotKeySet("^+7","get7")
HotKeySet("^+8","get8")
HotKeySet("^+9","get9")
$hGUI = GuiCreate("Clipboard Controller", 100, 100,Default,Default,$WS_SIZEBOX)
GUISetState()
Func addToClipboard()
Send ("^c")
$copied = ClipGet()
$clipBoard[Mod($counter,50)] = $copied
$counter +=1
EndFunc
Func getByIndex($i)
$statement = $clipBoard[$i]
ClipPut($statement)
Send("^v")
EndFunc
Func getAll()
$statement =""
For $i In $clipBoard
If $i <> "" Then
$statement &= $i & #CRLF
EndIf
Next
ClipPut($statement)
Send("^v")
EndFunc
Func emptyAll()
For $i=0 To 49
$clipBoard[$i]=""
Next
ClipPut("")
EndFunc
Func get1()
getByIndex(0)
EndFunc
Func get2()
getByIndex(1)
EndFunc
Func get3()
getByIndex(2)
EndFunc
Func get4()
getByIndex(3)
EndFunc
Func get5()
getByIndex(4)
EndFunc
Func get6()
getByIndex(5)
EndFunc
Func get7()
getByIndex(6)
EndFunc
Func get8()
getByIndex(7)
EndFunc
Func get9()
getByIndex(8)
EndFunc
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
Problem is an old trap...
It takes a small amount of time to copy to the clip board
especially large items..try a sleep after the Send
Func addToClipboard()
Send ("^c")
sleep(1000) ; try different values
$copied = ClipGet()
$clipBoard[Mod($counter,50)] = $copied
$counter +=1
EndFunc
anyway like your script..idea
The problem is the code for addToClipboard is running while the user still has the keys pressed down. As a result, the Send command designed to send just Ctrl+C is in effect sending Ctrl+Shift+C, so the text is never copied.
The solution is to wait for the user to raise those keys, using the _IsPressed function, then once all keys are released, execute the code. It may also be wise to disable the hotkey when you enter the function (and re-enable when you leave) so that holding the hotkey down for a long time doesn't keep triggering the function.
An alternative would be to send the WM_COPY message directly to the control with focus. This is not guaranteed to work for every control (though I'd be very surprised if it didn't). This would be a far more reliable method.
hope this is the end of the problem , I found another way to set/get data from clipboard , functions : _ClipBoard_SetData () & _ClipBoard_GetData() from library <Clipboard.au3> , after trying them it worked well , after all it seems like the problem was in setting and getting data from the clipboard..
will come later isA to assure whether its finally correct or not
I am trying to write a LotusScript to control a motor. The script I have for reading the bits seem to work fine, but I wish to add a stop button. I have all the commands for making the device stop, but the trouble I'm having is that whenever LotusScript is running through a loop, I cannot click on any of the other buttons.
Does anyone know a way around this???
The scripts I am using are below.
Thank-you kindly.
Andy Barlow
Sub readpositionsub
Dim send_string As String
Dim readString As String
Dim tempString As String
readString = ""
REM Sets the "movement" cell to 6 (the movement int)
[b1].contents = "6"
Do While [b1].contents <> "7"
readString = ""
statusBitString = ""
REM READ STATUS ===!!!===
REM Open the handle to the motor
handle = init_RS232(19200)
REM #1$ reads the status from the controller.
send_string = "#1$"+Chr$(13)
REM Ask the controller to store the results in bits
resultStatus=write_RS232 (handle,send_string)
REM Read Status by looping through all of the bits
For n=0 To 8
tempString = "*1234567"
sendReadCommand = read_RS232(handle,tempString)
If Mid(tempString,1,1) = Chr$(13) Then
Exit For
Else
statusBitString = statusBitString + Mid(tempString,1,1)
End If
Next
[b1].contents = Mid(statusBitString,7, 1)
close_RS232(handle)
REM End Read Status
REM READ POSITION ===!!!===
REM Open the handle to the motor
handle = init_RS232(19200)
send_string = "#1C"+Chr$(13)
t=write_RS232 (handle,send_string)
REM Reading Position
For n=0 To 20
tempString = "*1234567"
r = read_RS232(handle,tempString)
If Mid(tempString,1,1) = Chr$(13) Then
Exit For
Else
readString = readString + Mid(tempString,1,1)
End If
Next
REM End Read Position
[a1].contents=Mid(readString, 4)
close_RS232(handle)
Loop
End Sub
And the stop button that should work should be...
Object btnStop
Sub Click(Source As Buttoncontrol)
REM initialise
handle = init_RS232(19200)
REM Create the string for starting the motor
send_string = "#1S"+Chr$(13)
REM Send the string for starting the motor
resultStartMotor=write_RS232 (handle,send_string)
REM Close the spin handle
close_RS232(handle)
End Sub
You're not running your Lotusscript in a threaded environment, so how do you expect the code on a button to stop the code already running?
If you want to be able to cancel a loop you need to play with the timer object. Basically you start a time that executes one iteration of your loop. At the beginning you look for a changed field value or an ini variable to cancel the timer if set. Now you can use your button to set that variable.
The loop will run much slower than without a timer (after all it has a wait interval you set)